微服务框架相关技术
微服务整体框架APIGatewayAPIGateway两种方式:APIGateway的作用APIGateway的架构Eureka(服务发现框架)Eureka的两个组件RPC框架RPC定义RPC主要组成部分影响RPC框架性能的因素工业界的RPC框架如何选择RPC框架Dubbo核心组件工作原理Dubbo特性使用示例ZuulZuul工作原理Zuul的作用Zuul与应用的集成方式React前端框架React定义React核心React特点React的虚拟DOMReact的组件组件的三大属性props属性refs属性state属性组件的生命周期React的函数式编程React的JSXReact的其它操作双向绑定React发送ajax请求RESTfulRESTful的关键RESTful与RPCRESTfulWeb服务的Java框架RESTfulAPIRESTfulAPI设计原则RESTfulAPI设计规范RESTfulAPI对资源的操作微服务整体框架
开发前后台分离:前台与后台之间,通过Restful风格接口通信(HTTP协议)内部服务:Dubbo(RPC框架)外部服务:SpringCloudZuul(提供RestfulAPI接口)微服务应用开发
APIGateway
APIGateway:网关,统一应用请求接口.API网关在微服务们的最前端,让API网关变成由应用所发起的每个请求的入口,简化客户端实现和微服务应用程序间的沟通方式。APIGateway两种方式:
单节点APIGatewayBFF(Backendsforfrontends)GatewayAPIGateway的作用
请求路由,版本控制:APIGateway是微服务的入口,可以根据不同的请求路由到不同的服务上.也可以进行路由的版本控制,这样即使后服务发生了变化,Gateway的路径依然可以不改变用户登录,权限认证:客户端在与我们后端服务进行交互之前,由APIGateway先进行登录鉴权操作,这是后端所有的服务都需要有的共有逻辑数据聚合:由于不同的客户端往往需要的数据完全不同,而这些数据又是不同的service提供的,可以借助Gateway方便完成来自不同service的数据聚合协议转换:在项目实践中,CS(ClienttoServer)协议和SS(ServertoServer)协议是不一样的,为了保证数据传输的可靠性,CS协议会有鉴权以及加密解密的逻辑,而在内部的SS协议则不需要这些逻辑,因此在Gateway我们需要有一个协议转换的过程熔断,降级,限流:通过APIGateway可以在监测到某个服务发生异常,或者当服务的流量超过服务的承载能力等情况时,可以采取相应的措施.提高整个系统的容错性、稳定性负载均衡:APIGateway知道所有服务实例的地址,可以根据不同服务采取不同的负载均衡策略灰度发布:灰度发布允许直接只导入指定量的流量请求到新的版本APIGateway的架构
多网关集群(Backendsforfrontends):针对不同的客户端,都有相应的网关层来接入.功能主要有:用户登录,鉴权,服务发现注册,协议转换,接口版本控制等以及监控,APM调用链,日志,流控策略等聚合服务(MergeService):在某些客户端的需求中,需要从多个服务拉取数据,为了减少客户端的复杂度,以及加快客户端的访问速度,可以加一个聚合层,用来做聚合查询,在某些接口中可以把多个服务的数据一次性返回给客户端仪表盘管理端(Dashboard):Dashboard提供可视化的分析平台,包括服务的管理,监控数据报警配置,日志查询,灰度发布操作,API文档管理等Eureka(服务发现框架)
Eureka是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能Eureka的两个组件
EurekaServer:EurekaServer提供服务注册服务,各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中看到.EurekaServer之间通过复制的方式完成数据的同步EurekaClient:是一个java客户端,用于简化与EurekaServer的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性在应用启动后,将会向EurekaServer发送心跳,如果EurekaServer在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除。Eureka还提供了客户端缓存机制,即使所有的EurekaServer都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性RPC框架
RPC定义
RPC(RemoteProcedureCallProtocol):远程过程调用协议,一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.也就是客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样
RPC是协议:协议就是一套规范,目前典型的RPC实现包括:Dubbo,Thrift,GRPC,Hetty等.从目前技术的发展趋势来看,实现了RPC协议的应用工具往往都会附加其他重要功能网络协议和网络IO模型对其透明:既然RPC的客户端认为自己是在调用本地对象。那么传输层使用的是TCP/UDP还是HTTP协议,又或者是一些其他的网络协议它就不需要关心了。既然网络协议对其透明,那么调用过程中,使用的是哪一种网络IO模型调用者也不需要关心信息格式对其透明:我们知道在本地应用程序中,对于某个对象的调用需要传递一些参数,并且会返回一个调用结果。至于被调用的对象内部是如何使用这些参数,并计算出处理结果的,调用方是不需要关心的。那么对于远程调用来说,这些参数会以某种信息格式传递给网络上的另外一台计算机,这个信息格式是怎样构成的,调用方是不需要关心的应该有跨语言能力:调用方实际上也不清楚远程服务器的应用程序是使用什么语言运行的。那么对于调用方来说,无论服务器方使用的是什么语言,本次调用都应该成功,并且返回值也应该按照调用方程序语言所能理解的形式进行描述RPC主要组成部分
Client:RPC协议的调用方.最理想的情况是RPCClient在完全不知道有RPC框架存在的情况下发起对远程服务的调用.但实际情况来说Client或多或少的都需要指定RPC框架的一些细节Server:在RPC规范中,这个Server并不是提供RPC服务器IP,端口监听的模块。而是远程服务方法的具体实现(在JAVA中就是RPC服务接口的具体实现).其中的代码是最普通的和业务相关的代码,甚至其接口实现类本身都不知道将被某一个RPC远程客户端调用Stub/Proxy:RPC代理存在于客户端,因为要实现客户端对RPC框架“透明”调用,那么客户端不可能自行去管理消息格式、不可能自己去管理网络传输协议,也不可能自己去判断调用过程是否有异常。这一切工作在客户端都是交给RPC框架中的“代理”层来处理的MessageProtocol:一次完整的client-server的交互肯定是携带某种两端都能识别的,共同约定的消息格式.RPC的消息管理层专门对网络传输所承载的消息信息进行编码和解码操作.目前流行的技术趋势是不同的RPC实现,为了加强自身框架的效率都有一套(或者几套)私有的消息格式Transfer/NetworkProtocol:传输协议层负责管理RPC框架所使用的网络协议,网络IO模型.传输层还需要统一RPC客户端和RPC服务端所使用的IO模型Selector/Processor:存在于RPC服务端,用于服务器端某一个RPC接口的实现的特性(它并不知道自己是一个将要被RPC提供给第三方系统调用的服务).所以在RPC框架中应该有一种“负责执行RPC接口实现”的角色.包括:管理RPC接口的注册,判断客户端的请求权限,控制接口实现类的执行在内IDL:IDL(接口定义语言)并不是RPC实现中所必须的.但是需要跨语言的RPC框架一定会有IDL部分的存在.这是因为要找到一个各种语言能够理解的消息结构、接口定义的描述形式.如果RPC实现没有考虑跨语言性,那么IDL部分就不需要包括,例如JAVARMI因为就是为了在JAVA语言间进行使用,所以JAVARMI就没有相应的IDL不同的RPC框架实现都有一定设计差异。例如生成Stub的方式不一样,IDL描述语言不一样、服务注册的管理方式不一样、运行服务实现的方式不一样、采用的消息格式封装不一样、采用的网络协议不一样。但是基本的思路都是一样的,上图中的所列出的要素也都是具有的
影响RPC框架性能的因素
使用的网络IO模型:RPC服务器可以只支持传统的阻塞式同步IO,也可以做一些改进让RPC服务器支持非阻塞式同步IO,或者在服务器上实现对多路IO模型的支持.这样的RPC服务器的性能在高并发状态下,会有很大的差别.特别是单位处理性能下对内存,CPU资源的使用率基于的网络协议:一般来说可以选择让RPC使用应用层协议,例如HTTP或者HTTP/2协议,或者使用TCP协议.让RPC框架工作在传输层.工作在哪一层网络上会对RPC框架的工作性能产生一定的影响,但是对RPC最终的性能影响并不大.但是至少从各种主流的RPC实现来看,没有采用UDP协议做为主要的传输协议的消息封装格式:选择或者定义一种消息格式的封装,要考虑的问题包括:消息的易读性,描述单位内容时的消息体大小,编码难度,解码难度,解决半包/粘包问题的难易度.当然如果您只是想定义一种RPC专用的消息格式,那么消息的易读性可能不是最需要考虑的.消息封装格式的设计是目前各种RPC框架性能差异的最重要原因,这就是为什么几乎所有主流的RPC框架都会设计私有的消息封装格式的原因.dubbo中消息体数据包含dubbo版本号,接口名称,接口版本,方法名称,参数类型列表,参数,附加信息序列化和反序列化(SchemaDataSerialization):序列化和反序列化,是对象到二进制数据的转换,程序是可以理解对象的,对象一般含有schema或者结构,基于这些语义来做特定的业务逻辑处理.序列化框架一般会