Dubbo基础知识
加载点,SPI
以Transporter为例,通过SPI实例化的对象都是线程安全和单例
@SPI注解
SPI注解的value就是该接口实现的默认实现类,value的值对应META-INF下的接口同名文件内。比如这里,value = netty,在org.apache.dubbo.remoting.Transporter文件里,netty对应org.apache.dubbo.remoting.transport.netty4.NettyTransporter这个实现类
1 | // Transporter.java |
1 | // META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter |
@Adaptive注解
通过参数动态获取实现类。比如,传入的URL如果包含server=netty3或transporter=netty3,则使用netty3的实现类,即org.apache.dubbo.remoting.transport.netty.NettyTransporter
动态代理方式
- Javassist动态代理
- 通过代码字符串生成类对象
- JDK动态代理
- 将代码字符串包装成文件对象
通信实现(Transporter)
底层通信方式,org.apache.dubbo.remoting.Transporter
- netty
远程调用
调用流程
Cluster -> Invoker -> Router -> LoadBalance -> Invoker
客户端 -> 路由 -> 负载均衡 -> IO线程池(读写、序列化和反序列化)
Dubbo协议
构造Dubbo协议
org.apache.dubbo.remoting.exchange.codec.ExchangeCodec
对象序列化协议
org.apache.dubbo.common.serialize.Serialization
hessian2:默认。compactedjavajavanativejava
源码使用:
1 | // ExchangeCodec.class |
Dubbo容错机制
重试机制
Failover:默认。失败时重试其他服务器Failfast:快速失败。返回异常Failsafe:快速失败,不返回异常。用于一些不重要的请求Failback:失败后,加入重试队列,定时重试。适合异步或最终一致性的请求Forking:同时调用多个服务器,只要有一个返回则立即返回Broadcast:请求所有服务器,任何一个节点报错则报错。无需负载均衡Mock:请求失败后,返回伪造的结果Available:最简单的方式,不做负载均衡,找到一个可用节点即请求,如果没有找到则抛异常Mergeable:将多个节点的结果合并
负载均衡
org.apache.dubbo.rpc.cluster.LoadBalance
- 随机(
RandomLoadBalance):按权重随机。默认 - 轮询(
RoundRobinLoadBalance):按公约后的权重设置轮训比例- 普通权重轮询
- 平滑权重轮询
- 最少活跃调用次数(
LeastActiveLoadBalance):记下每个Invoker的活跃数(调用数)- 需配合
ActiveLimitFilter:统计方法调用次数
- 需配合
- 一致性hash(
ConsistentHashLoadBalance):相同参数的请求总会发到同一个提供者。基于虚拟节点,即是一个提供者宕机,也不会引起剧烈变动。默认160个虚拟节点 - 最短响应时间(
ShortestResponseLoadBalance)