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)))
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流程, 直接向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過程