RPC框架图
Dubbo模块解读
serialize层
-
IO线程数
- cpu核数+1
-
通讯框架
- 协议(netty,netty4,mina和grizzly)
- 启动:NettyServer
-
编解码
- NettyCodecAdapter
private final ChannelHandler encoder = new InternalEncoder(); private final ChannelHandler decoder = new InternalDecoder();
-
Codec2
- 实现:TransportCodec,TelnetCodec,ExchangeCodec,DubboCountCodec以及ThriftCodec
,也可自行扩展,默认是DubboCountCodec。dubbo通过配置文件配置的启动加载
- 实现:TransportCodec,TelnetCodec,ExchangeCodec,DubboCountCodec以及ThriftCodec
-
序列化
- dubbo提供多种序列化方式,通过url中获取serialization关键字,默认为hession2,提供的序列化方式:fastjson,fst,hessian2,java,compactjava,nativejava和kyro
每种序列化方式都需要实现如下三个接口类:Serialization,ObjectInput以及ObjectOutput;
- dubbo提供多种序列化方式,通过url中获取serialization关键字,默认为hession2,提供的序列化方式:fastjson,fst,hessian2,java,compactjava,nativejava和kyro
-
反序列化
反序列化通过读取header中的序列化类型,然后通过如下方法获取具体的Serialization
- CodecSupport
Transport层
-
Transporter类
-
提供统一的bind和connect接口,bind对服务端,connect对客户端
-
实现类有:nettyTransporter,MinaTransporter和GrizzyTransporter,具体使用哪种类型的Transporter,在Transporters类中提供了getTransporter方法
-
Server端和Client可以分别设置成不同的通讯框架,一次获取唯一的Transporter不能满足此需求;具体的生成动态代码的方法在ExtensionLoader的createAdaptiveExtensionClassCode方法中
-
-
Server端
-
通过调用父类AbstractServer的构造器,进行参数初始化,绑定端口,启动服务器,主要从url获取启动参数:Ip,Port,accepts,idleTimeout,调用doOpen()启动服务
-
过程:
nettyHandler;server端在数据经过解码之后就交给NettyHandler来处理,NettyHandler继承于Netty的SimpleChannelHandler类, 重写了channelConnected,channelDisconnected,messageReceived,writeRequested以及exceptionCaught方法, 基本上就是常规的几种操作:建立连接,断开连接,接收消息,发送消息,异常处理
-
-
Client端
-
客户端提供重连机制,send_reconnect:发送消息时发现连接已经断开是否发起重连;reconnect_warning_period表示多久报一次重连警告,shutdown_timeout表示连接服务器一直连接不上的超时时间;
-
过程:首先判定是否已经连接,如果连接直接return;接下来初始化连接状态检查器,定期检查channel是否连接,连接断开会进行重连操作
-
Exchange层
-
Exchanger:提供bind和connect接口,返回ExchangeClient和ExchangeServer
-
ExchangeClient
- 创建了一个Request,在构造器中同时会产生一个RequestId;设置了协议版本,是否双向通信,最后设置了真实的业务数据;接下来实例化了一个DefaultFuture类,此类实现了同步转异步的方式
-
ExchangeResponse
-
服务器端主要用于接收Request消息,然后处理消息,最后把响应发送给客户端
-
通过Request的信息,反射调用Server端的服务,然后返回结果,然后将结果放入Response对象中,通过channel将消息发送客户端
-
Protocol层
-
Protocol接口:提供export(Invoker invoker)和refer(Class type,Url url)
-
export():暴露远程服务
-
refer():引用远程服务
-
协议,dubbo协议是默认的协议,其他扩展协议包括:hessian,http,injvm,redis,rest,rmi,thrift,webservice等。也可扩展协议,分别实现Protocol,Export,Invoke
-
-
DubboProtocol类
-
refer
在客户端定一个的每个dubbo:reference,都会在此处实例化一个对应的DubboInvoker;在方法内部首先对序列化优化进行处理,
主要是对Kryo,FST等序列化方式进行优化,此方法不仅在客户端,同时服务器端也存在;接下来就是创建了一个DubboInvoker,同时创建与服务器端的连接: -
export()
每个dubbo:service都会绑定一个Exporter,首先通过url获取一个key(包括:port,serviceName,serviceVersion,serviceGroup),
然后将实例化的DubboExporter通过key值保存在一个Map中,后续在接收到消息的时候从新定位到具体的Exporter -
DubboInvoker
在DubboInvoker的抽象类中提供了invoke方法,做统一的附件(Attachment)处理,方法传入的参数是一个RpcInvocation对象,包含了方法调用的相关参数:
方法名称,方法参数,参数值,附件信息等- ExchangeClient将RpcInvocation发送给服务器端,提供了三种发送方式:单边通信方式,双边通信(同步),双边通信(异步)
-
cluster层
此层封装了多个提供者路由,负载均衡,桥接注册中心,以Invoker为中心,可扩展接口未Cluster,Direcotry,Router和LoadBlance
-
Cluster接口
-
cluster是一个集群容错的接口,经过目录,路由,负载均衡获取到一个可用的Invoker,交给上层调用,由容错机制处理,dubbo提供的容错机制:
-
Failover Cluster:失败自动切换
-
failfast: 快速失败
-
failsafe:失败安全
-
failback:失败自动恢复
-
Forking :并行调用
-
Broadcast :广播调用
-
-
-
FailOverCluster类
-
实现在FailoverClusterInvoker中
-
过程:invocation是客户端传给服务器的相关参数包括(方法名称,方法参数,参数值,附件信息),invokers是经过路由之后的服务器列表,loadbalance是指定的负载均衡策略;首先检查invokers是否为空,为空直接抛异常,然后获取重试的次数默认为2次,接下来就是循环调用指定次数,如果不是第一次调用(表示第一次调用失败),会重新加载服务器列表,然后通过负载均衡策略获取唯一的Invoker,最后就是通过Invoker把invocation发送给服务器,返回结果Result
-
-
Directory接口
-
目录服务作用就是获取指定接口的服务列表,具体实现有两个:StaticDirectory和RegistryDirectory,同时都继承于AbstractDirectory;
-
StaticDirectory:是一个固定的目录服务,表示Invoker列表不会改变
-
RegisteryDirectory:是一个动态的目录服务,表示注册中心动态更新服务列表;
-
NotifyLister#notify:是一个通知接口,包含:router(路由),configuation(配置),provider服务提供方
-
-
Router接口
- 实现:ScriptRouter,ConditionRouter和MockInvokersSelector
-
LoadBalance接口
-
dubbo提供多种负载策略,默认是random
-
提供的策略:
-
Random LoadBalance:随机,按权重设置随机概率
-
RoundRobin LoadBalance:轮询,按公约后的权重设置轮询比
-
LeastActive LoadBalance:最少活跃调用数
-
ConsistentHash LoadBalance:一致性 Hash
-
-
register层
-
作用:封装了服务的注册和发现,以URL为中心,扩展接口:RegisterFactroy,Register,RegistrService
-
Register接口
- 作用:提供注册,注销,订阅,退订等。dubbo提供了multicast,zookeeper,redis,sample等
-
RegisterFactory接口
- ZookeeperRegistryFactory
-
Zookeeper注册中心
- 流程:RegistryFactory实例化Registry,Registry可以接收RegistryProtocol传过来的注册(register)和订阅(subscribe)消息,
然后Registry通过ZKClient来向Zookeeper指定的目录下写入url信息,如果是订阅消息Registry会通过NotifyListener来通知RegitryDirctory进行更新url,最后就是Cluster层通过路由,负载均衡选择具体的提供方;
- 流程:RegistryFactory实例化Registry,Registry可以接收RegistryProtocol传过来的注册(register)和订阅(subscribe)消息,