Dubbo知识总结
Remoting:网络通信框架
RPC:一个远程调用的抽象,支持负载均衡,容灾,集群等功能
Register:服务目录框架用于服务的注册和服务事件的发布订阅
Provider:暴露服务的提供方
Consumer:调用远程服务的服务消费方
Registry:服务注册中心与发现中心
Monitor:统计服务和调用次数,调用时间监控中心
Container:启动服务的容器
服务者注册流程
1、声明注册中心
2、声明通信协议,暴露服务端口
3、对外暴露可以提供的接口服务
消费者注册流程
1、声明应用名
2、声明注册中心
3、注册需要依赖的服务
主要配置
dubbo:service 服务配置,提供失败重试机制,用于暴露一个服务,一个服务可以用多个协议暴露,也可以注册到多个注册中心
dubbo:reference 引用配置,创建一个远程服务代理,一个引用可以指向多个注册中心
dubbo:protocol 协议配置,用于配置提供服务的协议信息,协议有提供方指定,消费者被动接受
dubbo:application 应用配置,用于配置当前应用的信息,不管改应用是提供者还是消费者
dubbo:module 模块配置,用于配置当前模块信息,可选
dubbo:registry 注册中心配置,用于配置连接注册中心的相关信息
dubbo:monitor 监控中心配置,用于配置连接监控中心的相关信息,可选
dubbo:provider 提供方配置,当ProtocalConfig和ServiceConfig某属性没有配置是,采用此缺省值,可选
dubbo:consumer 消费方配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选,启动检查,如果所需服务在注册中心找不到,报错处理,
dubbo:method 方法配置,用于ServiceConfing和ReferenceConfig指定方法级和配置信息
dubbo:argument 参数配置,用于指定方法参数配置
0、服务器负责启动,加载,运行服务提供者
1、提供者在启动时,向注册中心注册自己提供的服务
2、消费者在启动时,向注册中心订阅自己所需要的服务
3、注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心会及时通知服务消费者
4、消费者,从远程接口列表中,调用远程接口,dubbo会基于负载均衡算法,选一台提供者进行服务调用,如果调用失败则选择另外一台
5、提供者和消费者,在内存中累计调用次数和调用时间等信息,定时发送统计数据到监控中心
Dubbo核心层级
1、服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
2、配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
3、服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
4、服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。
可能没有服务注册中心,此时服务提供方直接暴露服务。
5、集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。
将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
6、监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
7、远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。
Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。
Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,
也可能是一个远程的实现,也可能一个集群实现。
8、信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
9、网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
10、数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
Dubbo流程
1、在RPC中,Protocol是核心层,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC调用,然后在Invoker的主过程上Filter拦截点。
2、图中的Consumer和Provider是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,
不用Client和Server的原因是Dubbo在很多场景下都使用Provider、Consumer、Registry、Monitor划分逻辑拓普节点,保持统一概念。
3、而Cluster是外围概念,所以Cluster的目的是将多个Invoker伪装成一个Invoker,这样其它人只要关注Protocol层Invoker即可,
加上Cluster或者去掉Cluster对其它层都不会造成影响,因为只有一个提供者时,是不需要Cluster的。
4、Proxy层封装了所有接口的透明化代理,而在其它层都以Invoker为中心,只有到了暴露给用户使用时,才用Proxy将Invoker转成接口,或将接口实现转成Invoker,
也就是去掉Proxy层RPC是可以Run的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。
5、而Remoting实现是Dubbo协议的实现,如果你选择RMI协议,整个Remoting都不会用上,Remoting内部再划为Transport传输层和Exchange信息交换层,
Transport层只负责单向消息传输,是对Mina、Netty、Grizzly的抽象,它也可以扩展UDP传输,而Exchange层是在传输层之上封装了Request-Response语义。
6、Registry和Monitor实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起。
Dubbo
连接个数:单链接
连接方式:长连接
传输协议:TCP
传输方式:NIO异步传输
序列化:Hessian 二进制序列化
适用场景:常规远程服务方法调用
Rmi
连接个数:多连接
连接方式:短连接
传输协议:TCP
传输方式:同步传输
序列化:Java标准二进制序列化
适用场景:常规远程服务方法调用,与原生RMI服务互操作
Hessian
连接个数:多连接
连接方式:短连接
传输协议:HTTP
传输方式:同步传输
序列化:Hessian二进制序列化
适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
适用场景:页面传输,文件传输,或与原生hessian服务互操作
Http
连接个数:多连接
连接方式:短连接
传输协议:HTTP
传输方式:同步传输
序列化:表单序列化
适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
适用场景:需同时给应用程序和浏览器 JS 使用的服务。
WebService
连接个数:多连接
连接方式:短连接
传输协议:HTTP
传输方式:同步传输
序列化:SOAP 文本序列化
适用场景:系统集成,跨语言调用
负载权衡策略
random:随机,按权重设计随机概率
roundRobin:轮询,按公约后的权重设置轮询比率
leastActive:最少活跃调用数,相同活跃数的随机,使慢的处理者收到更少的请求
consistentHash:一致性哈希,使得相同参数的请求总是发到同一提供者
集群容错机制
Failover Cluster:失败自动切换,出现失败,重试其他服务器。用于读操作,但重试会带来更长延迟,可以声明重试次数
Failfast Cluster:快速失败,直发器一次调用,失败立报错。通常用语非幂等性的写操作
Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作
Faileback Cluster:失败后自动恢复,后台记录失败的请求,定时重发。通常用于消息通知等操作
Forking Cluster:并行调用多个服务器,只要有一个成功就返回,通常用语实时性要求比较高的读操作,可以通过forks="2",设置最大并行数
Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用语通知所有提供者更新缓存或者日志等本地资源信息
线程模型
需要通过不同的派发策略和不同的线程池配置的组合来应对不同的场景:
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
Dispatcher
all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。
message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
ThreadPool
fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
cached 缓存线程池,空闲一分钟自动删除,需要时重建。
limited 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
eager 优先创建Worker线程池。在任务数量大于corePoolSize但是小于maximumPoolSize时,优先创建Worker来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列中。
阻塞队列充满时抛出RejectedExecutionException。(相比于cached:cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列)
借鉴文章:
http://blog.51cto.com/13732225/2295896
http://www.cnblogs.com/wangzhuxing/p/9735258.html