20. Dubbo原理解析-通信层之引用服务

二:消费方引用服务

服务调用方在引用服务refer时候创建对服务提供者的链接:构建DubboInvoker时候需要获取ExchangeClient作为构造器参数传入

Exchangers.connect(url, requestHanler)à HeaderExchanger.connect(url,exhangeHandler)

       构建HeaderExchangeClient,获取传输层作为构造器参数Transporters.connect(url, channelHannler)à NettyTransporter.connect(url,channelHandler)

       构建NettyClient(url, channelHandler)返回

             

HeaderExchange中装饰 ChannelHandler  new DecodeHandler(new HeaderExchange Handler(requestHandler)))

在NettyClient构造器中装饰了ChannelHandler

new MultiMessageHandler(newHeartbeatHandler(ExtensionLoader.getExtension Loader(Dispatcher.class).getAdaptiveExtension().dispatch(handler,url)))

 

ExtensionLoader.getExtensionLoader(Dispatcher.class).getAdaptiveExtension().dispatch(handler, url))= AllChannelHandler

 

requestHandler是在DubboProtocol中实现的ExchangeHandlerAdapter

 

 

DubboInvokeràReferenceCountExchangeClient àHeaderExchangeClientà HeaderExchangeChannelàNettyClient

DubboInvoker根据Invocation对象判断是同步异步还是单向调用。选取ExchangeClient如果是共享的返回唯一的那个,如果不是,轮询获取一个。

ReferenceCountExchangeClient.request  没做什么事情,直接调下一个

HeaderExchangeClient.request 调ExhangeChannel的request方法

HeaderExchangeChannel的request方法

将请求转换成Request对象,构建Request对象,将入参(如:Invocation)设置到data属性上, 构建DefaultFuture,这里同步转异步返回

由HeaderExchanger构建的client根据spi策略默认为NettyClient, 所以下一步回调nettyClient.send(request)

返回DefaultFuture对象

NettyClient的send流程

获取com.alibaba.dubbo.remoting.transport.netty.NettyChannel,  NettyChannel覆写client方法,根据netty跟server建立的链接获取的org.jboss.netty.channel.Channel,在利用NettyChannel来构建获取从缓存总获取。com.alibaba.dubbo.remoting.transport.netty.NettyChannel封装了netty通道channel,统一数据模型url以及channelHandler

下一步调NettyChannel的send方法

NettyChannel的send流程, 直接向org.jboss.netty.channel.Channel中写入Request数据

DefaultFuture.get() 获取响应接口

 

 

NettyHandler继承了netty的SimpleChannelHandler类

messageReceived接收对方的数据

       获取nettychannel, nettyClient.receive(nettychannel, response)

NettyClient.received

MultiMessageHandler.received(nettyChannel,response)

HeartbeatHandler.received(nettyChannel,response)

       设置read时间戳

       如果心跳请求,发送心跳

       如果心跳响应 返回

       其他下一步handler处理

AllChannelHandler, 构建异步执行任务ChannelEventRunnable,异步执行

ChannelEventRunnable.received(nettychannel,response)

DecodeHandler.received(nettychannel,response)

       Decode(response.getResult)

       下一步handler处理

HeaderExchangeHandler.received(nettychannel, response)

       给nettychannel设置READ_TIMESTAMP时间戳

       从缓存获取或者构建HeaderExchangeChannel

       handleResponse(headerExchangeChannel,response)如果不是心跳DefaultFuture.received(headerExchangeChannel,response)

       根据response的id获取请求时构建的DefaultFuture 

       doReceive(response) 赋值response对象值,done.signal()唤醒Condition前端同步get流程

DefaultFuture.get()

       done.await(timeout,TimeUnit.MILLISECONDS);

被唤醒后从returnFromResponse()方法获取, response.getResult() 返回DecodeableRpcResult对象

      

 

下面给出服务消费方连接服务提供方的connect过程

代码交流 2021