一、dubbo简单原理
主要包括五个节点:Provider、Consumer、Container、Register、Monitor
Provider:服务提供者
Consumer:服务订阅者
Container:服务运行的容器
Register:注册中心
Monitor:监控中心,统计服务调用次数和调动时间
dubbo工作过程:
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
二、dubbo架构原理
dubbo架构有10层:
service层(接口层):给服务提供者和消费者实现的(留给开发人员实现)
config层(配置层):针对dubbo进行各种配置。
proxy层(服务代理层):服务提供者调用的是接口,需要实现类,所以先生成动态代理类。
registry层(服务注册层):负责服务的注册与发现
cluster层(集群层):封装多个服务提供者的路由及负载均衡,将多个实例组合成一个服务。
monitor层(监控层):对rpc接口的调用次数和调用时间进行监控。
protocol层(协议层)(远程调用层):封装rpc调用,使用不同协议,如:dubbo、rest、……等。
exchange层(信息交换层):封装请求响应模式,同步转异步。
transport层(网络传输层):封装netty和mina为统一接口。
serialize层:(数据序列化层):用于序列化数据。
上图的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。
Directory代表多个Invoker,可以把它看成List,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。
Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。
Router负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等。
LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。
把实现类通过javassistProxyFactory 变成 Invoker
1、dubbo xml配置文件解析过程
dubbo.xml头内容如下:
包含一个名字为dubbo的命名空间,把dubbo.xml引入Spring之后,Spring会找到spring.handlers文件,找到对应的命名空间处理器DubboNamespaceHandler
同时 DubboNamespaceHandler继承了spring的NamespaceHandlerSupport,会执行init方法,初始化解析器,有application、module、registry……等很多。
然后解析到ApplicationConfig、ModuleConfig、RegistryConfig、MonitorConfig……等配置文件中,并加入bean容器
2、dubbo 服务是如何暴露的
Dubbo会在Spring实例化完bean之后,在刷新容器最后一步发布ContextRefreshEvent事件的时候,通知实现了ApplicationListener的ServiceBean类进行回调onApplicationEvent 事件方法,dubbo会在这个方法中调用ServiceBean父类ServiceConfig的export方法,而该方法真正实现了服务的(异步或者非异步)发布。
简述:
首先会检查各种配置信息,填充各种属性,保证所有的东西是正确的。
加载所有的注册中心,因为我们暴露服务需要注册到注册中心中去。(doExportUrls方法调用loadRegistries获取所有的注册中心url)
根据配置的所有协议和注册中心url分别进行导出。
如果配置的不是remote,则做本地导出(injvm协议)。
如果配置的不是local,则暴露为远程服务(判断是否延迟暴露)。
不管是本地还是远程服务暴露,首先都会获取Invoker。
获取完Invoker之后,转换成对外的Exporter,缓存起来。
3、dubbo 服务的调用过程
1、调用过程从一个Proxy开始,Proxy持有了一个Invoker对象。
2、然后触发invoke调用。在invoke调用过程中,需要使用Cluster。
3、在调用之前会通过Directory获取所有可以调用的远程服务Invoker列表。接下来就会调用LoadBalance方法做负载均衡,最终选出一个可以调用的Invoker。
4、这个Invoker在调用之前又会进入一个过滤器链,这个过滤器链通常是处理上下文、限流、计数等。
5、接着,会使用Client做数据传输。此时就会用到Codec接口做私有协议的构造。
6、构造完成之后,就对数据包做序列化(Serialization),然后传输到服务提供者端。
7、服务提供者接收到数据包,也会使用Codec处理协议头及一些半包、粘包等。处理完成之后再对完整的数据报文做反序列化处理。
8、随后,这个Request会被分配到线程池(ThreadPool)中进行处理。Server会处理这些Request,根据请求查找对应的Exporter(它内部持有了Invoker。Invoker是被用装饰器模式一层一层套了很多Filter的,因此在调用最终的实现类之前,又会经过一个服务提供者端的过滤器链。)
9、最终,原路返回结果。
4、dubbo心跳机制
目的:检测provider与consumer之间的connection连接是不是还连接着,如果连接断了,需要作出相应的处理。
原理:
provider:dubbo的心跳默认是在heartbeat(默认是60s)内如果没有接收到消息,就会发送心跳消息,如果连着3次(180s)没有收到心跳响应,provider会关闭channel。
consumer:dubbo的心跳默认是在60s内如果没有接收到消息,就会发送心跳消息,如果连着3次(180s)没有收到心跳响应,consumer会进行重连。
三、dubbo支持哪些的通信协议
1、dubbo 默认协议:
单一 TCP 长连接,Hessian 二进制序列化和 NIO 异步通讯
适合于小数据包大并发的服务调用和服务消费者数远大于服务提供者数的情况
不适合传送大数据包的服务
2、rmi 协议:
采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式
如果服务接口继承了 java.rmi.Remote 接口,可以和原生 RMI 互操作
对传输数据包不限,消费者和传输者个数相当
3、hessian 协议:
底层 Http 通讯,Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现
可与原生 Hessian 服务互操作
通讯效率高于 WebService 和 Java 自带的序列化
参数及返回值需实现 Serializable 接口,自定义实现 List、Map、Number、Date、Calendar 等接口
适用于传输数据包较大,提供者比消费者个数多,提供者压力较大
4、http 协议:
基于 http 表单的远程调用协议,短连接,json 序列化
对传输数据包不限,不支持传文件
适用于同时给应用程序和浏览器 JS 使用的服务
5、webservice 协议:
基于 Apache CXF 的 frontend-simple 和 transports-http 实现,短连接,SOAP文本序列化
可与原生 WebService 服务互操作
适用于系统集成、跨语言调用
6、thrift 协议:
对 thrift 原生协议 [2] 的扩展添加了额外的头信息
使用较少,不支持传 null 值
7、基于 Redis实现的 RPC 协议
8、基于 Memcached 实现的 RPC 协议
四、dubbo集群容错模式
1、failover cluster(故障转移模式)
失败自动转换,当失败时重试其他的服务器。(缺省)
用于读操作,但重试会带来更长的延迟。使用retries="2"来设置重试次数(不含第一次)
2、failfase cluster(快速失败模式)
快速失败,只发起一次调用,失败立即报错
用于非幂等性的写操作,比如新增记录
3、failsafe cluster(安全失败模式)
失败安全,出现异常直接忽略
用于写入审计日志等操作
4、failback cluster(故障恢复模式)
失败自动恢复,后台记录失败请求,定时重发
用于消息通知等操作
5、forking cluster(并行调用模式)
并行调用多个服务器,只要一个成功即返回。
用于实时性要求高的读操作,但是浪费更多资源。使用forks=“2”来设置最大并行数
6、broadcast cluster(广播模式)
广播调用所有提供者,逐个调用,任意一台报错则报错
用于通知所有提供者更新缓存或日志等本地资源
五、dubbo负载均衡策略
1、RandomLoadBalance 随机
按权重设置随机概率
2、RoundRobinLoadBalance 轮询
3、LeastActiveLoadBalance 最少活跃调用数。
相同活跃数按随机。活跃数指调用前后计数差,因为响应慢的提供者收到的请求变少,计数差距逐渐拉开。
4、ConsistentHashLoadBalance 一致性Hash
相同参数的请求总是发送到同一提供者
六、dubbo的序列化机制
1、hessian2
跨语言的高效二进制序列化方式
2、FastJson
json字符串
2、java、compactedjava、nativejava
属于java原生序列化
3、kryo、fst
FST fast-serialization 是重新实现的 Java 快速对象序列化的开发包
Kryo是用于Java的快速高效的二进制对象图序列化框架。该项目的目标是高速,小尺寸和易于使用的API。每当需要将对象持久保存到文件,数据库还是通过网络时,该项目都是有用的。
Kryo还可以执行自动的深浅复制/克隆。这是从对象到对象的直接复制,而不是从对象到字节的复制。
标签:dubbo,调用,服务,Invoker,服务提供者,原理,序列化 From: https://blog.51cto.com/u_16111396/7340302