分布式服务框架通常能够分为如下几个部分,算法
(1)RPC基础层:spring
包括底层通讯框架,如NIO框架、通讯协议,序列化和反序列化协议,性能优化
以及在这几部分上的封装,屏蔽底层通讯细节和序列化方式差别服务器
(2)服务发布/消费:网络
服务提供者根据消费者请求消息中的接口名,方法名,参数列表等信息,经过Java反射,调用本地的接口实现类;架构
服务消费者将服务提供者发布的接口封装成远程服务调用;并发
(3)服务调用链:负载均衡
在服务调用的职责链中,经过在调用链切面的编码完成相关的监控和扩展,如负载均衡,服务调用性能统计,调用完成通知,框架
失败重发等功能异步
(4)服务注册中心:
注册中心负责服务的发布和通知,须要支持服务的平滑上线下线等
(5)服务治理中心:
服务治理中心是一个可视化的模块,提供对服务的可视化分析和维护,包括服务运行状态,调用关系和健康度等
下面以Dubbo为例来分析分布式服务框架的结构。
(1)系统角色
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
(2)调用关系
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册本身提供的服务。
服务消费者在启动时,向注册中心订阅本身所需的服务。
注册中心返回服务提供者地址列表给消费者,若是有变动,注册中心将基于长链接推送变动数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,若是调用失败,再选另外一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
Dubbo的整体架构如图所示:
框架分层架构中,各个层次的设计要点:
数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、
ObjectInput、ObjectOutput和ThreadPool。
推荐一个交流学习群:478030634 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多:
(1)协议支持
Dubbo支持多种协议,以下所示:
Thrift协议 Memcached协议 Redis协议
在通讯过程当中,不一样的服务等级通常对应着不一样的服务质量,那么选择合适的协议即是一件很是重要的事情。你能够根据你应用的建立来选择。例如,使用RMI协议,通常会受到防火墙的限制,因此对于外部与内部进行通讯的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。
(2)默认使用Dubbo协议
链接个数:单链接
链接方式:长链接
传输协议:TCP
传输方式:NIO异步传输
序列化:Hessian二进制序列化
适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者没法压满提供者,尽可能不要使用dubbo协议传输大文件或超大字符串
使用场景:常规远程服务方法调用
从上面的适用范围总结,dubbo适合小数据量大并发的服务调用,以及消费者机器远大于生产者机器数的状况,不适合传输大数据量的服务好比文件、视频等,除非请求量很低。
(3)Dubbo源码模块图
Dubbo以包结构来组织各个模块,各个模块及其关系,如图所示:
能够经过Dubbo的代码(使用Maven管理)组织,与上面的模块进行比较。简单说明各个包的状况:
(1)服务提供者暴露一个服务的详细过程
服务提供者暴露服务的主过程:
首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl),而后经过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,
到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。
Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程(如上图中的红色部分),下面咱们以Dubbo和RMI这两种典型协议的实现来进行说明:
Dubbo的实现
Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各类请求,通信细节由Dubbo本身实现。
RMI的实现
RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,
它经过Spring或Dubbo或JDK来实现RMI服务,通信细节这一块由JDK底层来实现,这就省了很多工做量。
(2)服务消费者消费一个服务的详细过程
服务消费的主过程:
首先ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。
接下来把Invoker转换为客户端须要的接口(如:HelloWorld)。