Dubbo的整个远程通信层由exchange,transport, serialize
exchange,信息交换层,封装请求响应模式,同步转异步,以Request, Response为中心,扩展接口为Exchanger, ExchangeChannel, HeaderExchangeHandler,ExchangeClient, ExchangeServer
transport,网络传输层,抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel, Transporter, Client, Server,Codec
serialize,数据序列化层,可复用的一些工具,扩展接口为Serialization, ObjectInput, ObjectOutput,ThreadPool
一:提供方暴露服务
1. 服务提供方在DubboProtocol暴露服务export的过程
DubboProtocol构建requestHandler实现了reply方法,用来响应服务调用方的请求,调用具体的服务,并将请求结果封装为RpcResult返回给调用方
requestHandler在创建服务createteServer的 Exchanger bind的时候传入,
Exchangers.bind(url, requestHandler) //传入url, 处理器,这个处理器会被层层装饰
根据spi策略HeaderExchanger.bind(url,requestHandler)
构建HeaderExchangeServer对象,new HeaderExchangeServer(Transporters.bind(url,new DecodeHandler(new HeaderExchangeHandler(handler))))
装饰requestHandler对象
根据spi策略NettyTransporter.bind(url, channelHandler), 构建NettyServer对象,绑定netty服务启动服务监听
2. NettyServer初始化过程,它是dubbo默认的通讯框架
构造器入参URL统一数据模型包含服务器端地址,超时时间等参数
构造器中装饰传入的ChannelHandler,ChannelHandler其实是一个处理器链,transporter层做了装饰,这里NettyServer构造其中通过ChannelHandlers.wrap方法再次进行装饰
RequestHandleràDecodeHandlerà HeaderExchangeHandlerà MultiMessageHandlerà
HeartbeatHandlerà AllChannelHandler
NettyServer的构造其中会调doOpen方法启动netty。 Netty是基于pipeline管道机制的,我们可以添加阀(org.jboss.netty.channel.ChannelHandler)来实现自己的需求
Decoder: InternalDecoder继承netty对象SimpleChannelUpstreamHandler
Dubbo自定义了一套buffer用来适配底层的nio, 自定的channelBuffer读取netty传递过的字节然后调用dubbo的编码解码器codec.decode解码成Request/Response对象返回
触发netty的messageReceived事件
Encoder:InternalEncoder继承于netty的OneToOneEncoder, 将传入的Request/Response/String等对象类型转换成字节流
注:为什么Decoder对象没有直接继承于netty的OneToOneDecoder对象能,因为decoder
时候要把字节流读入到dubbo自定义的buffer中,然后再调codec,这样codec的接口就不直接依赖于nio的api,便于codec的扩展及替换
3. NetttyHandler:继承于netty对象SimpleChannelHandler触发netty事件来处理dubbo需求,它会触发一系列的dubbo的ChannelHandler。它是一个处理链AllChannelHandlerà MultiMessageHandlerà HeartbeatHandleràDecodeHandler HeaderExchangeHandler à RequestHandler
AllChannelHandler: 默认分发请求实现对于netty事件中除了writeRequested的其他请求chanenlConnected, channelDisconnected,messageReceived, exceptionCaught这四种事件通过构建ChannelEventRunnable任务放入线程池分发
MultiMessageHandler:对于消息的received事件,如果消息是批量传输的decode后会由MultiMessage承载,如果是MultiMessage遍历其中的消息分别交由下一个handler处理
4. HeartbeatHandler:处理心跳
Connected事件设置读写时间戳为当前时间
Disconnected事件清空读写时间戳
Sent事件发送请求设置写时间戳为当前时间
Received事件接收请求设置读时间戳为当前时间
1) 判断消息是心跳请求,当Request对象的mEvent属性为true且mData为null时为心跳事件。
如果此心跳事件需要响应即Request.isTwoway(), 构建心跳响应对象Response,设置响应对象的mEvent=true && mData=null
下面channel处理,最终会通过netty响应客户端。
2) 判断消息是心跳响应,Response的mEvent=true && mData=null, 记录日志直接返回,不在做后续的channel处理了。
3) 如果不是心跳处理,交由下一个处理器处理。
5. DecodeHandler:对于读取的消息或者消息的数据实现了Decodeable接口的decode
6. HeaderExchangeHandler:这里已经到了交换层的handler了,对于这个handler我们主要关心sent事件: 设置channel的写时间戳, 交由后面hanler来发送消息,如果消息是request,根据request获取DefaultFuture设置它的发送时间为当前时间,用来判断是否超时。received事件:接收读取数据
1) 给channel设置读取时间戳
2) 如果是msg是请求类型的Reqeust,
根据request的id构建response对象
调DubboProtocol中构建的requestHandler的replay方法,返回调用结果
跟response对象设置返回结果
Channel.send(response) 向客户端发送响应
3) 如果读取的数据是Response响应并且不是心跳
根据response透传的id获取defaultFuture, 设置defaultFulture的response的值,唤醒线程,defaultFulture的get方法返回调用值
4) 如果是string类型, 处理telnet命令
5) 其他的交由下一个handler处理 //什么场景??
下面给出服务提供方服务绑定的活动图