官术网_书友最值得收藏!

3.2 Dubbo服務提供方如何處理請求

我們先看看當消費端發起TCP鏈接并完成后,在接收消費端發來的請求時,服務提供方是如何處理的,其處理時序圖如圖3.6所示。

圖3.6

讓我們看看圖3.6中的connected部分(步驟1~步驟11),消費端發起TCP鏈接并完成后,服務提供方的NettyServer的connected方法會被激活,該方法的執行是在Netty的I/O線程上執行的,為了可以及時釋放I/O線程,Netty默認的線程模型為All,正如在第7章所介紹的,所有消息都派發到Dubbo內部的業務線程池,這些消息包括請求事件、響應事件、連接事件、斷開事件、心跳事件等,這里對應的是AllChannelHandler類把I/O線程接收到的所有消息包裝為ChannelEventRunnable任務并都投遞到了線程池里。

線程池里的任務被執行后,最終會調用DubboProtocol的connected()方法,其代碼如下:

其中,invoke()是一個通用方法,其代碼如下:

其中,createInvocation()方法的代碼如下:

在這里的URL內不包含Constants.ON_CONNECT_KEY,所以直接返回了null。

圖3.6中的received部分(步驟12~步驟22)類似于connected,received事件被投遞到線程池后進行異步處理。線程池任務被激活后調用了HeaderExchangeHandler的received()方法,其代碼如下:

如果請求不需要響應結果則直接調用DubboProtocol的received()方法,否則執行handleRequest()方法,后者代碼如下:

如果請求需要返回值則執行handleRequest()方法,其也是委托給DubboProtocol的reply()方法來執行的。如果執行結果已經完成,則直接將結果寫回消費端,否則使用異步回調方式(避免當前線程被阻塞),等執行完畢并拿到結果后再把結果寫回消費端。

通過圖3.6可知,無論消費端是否需要執行結果,最終都是DubboProtocol類的reply()方法來執行具體的服務,下面我們看看reply()方法的代碼:

代碼7首先使用getInvoker()方法獲取調用方法對應的DubboExporter對象導出的Invoker對象,具體代碼如下。在3.1節中我們介紹了導出的DubboExporter對象會保存到exporterMap中,這里的getInvoker獲取的是RegistryProtocol$InvokerDelegate:

代碼8把對端的地址設置到上下文對象中。

代碼9執行導出的Invoker的invoke()方法,這里有個調用鏈,經過調用鏈后最終調用了服務提供方啟動時AbstractProxyInvoker代理類創建的invoke()方法,其調用時序如圖3.7所示。

圖3.7

圖3.7顯示的是調用DubboProtocol的reply()方法的情況,在調用InvokerDelegate的invoke()方法前會先經過Filter鏈(這里只列出來了Filter鏈中的一部分Filter),然后InvokerDelegate會調用服務提供方啟動時AbstractProxyInvoker代理類的invoke()方法,其代碼如下:

代碼11獲取上下文對象,代碼11.1調用doInvoke()方法,并使用JavaAssist來執行本地服務,以便減少反射調用,這里我們再回顧一下doInvoke()方法的代碼:

通過上面的代碼可知,AbstractProxyInvoker的doInvoke()方法委托Wrapper類的invokeMethod執行具體邏輯,后者則通過調用服務提供方接口的實現類來執行本地服務,細節可參考2.5.4小節。

需要注意的是,步驟11.2返回的結果是區分情況的,如果返回值類型為CompletableFuture,或者如果是使用RpcContext.startAsync()開啟異步執行的,則返回AsyncRpcResult對象,否則返回正常的RpcResult對象,我們在隨后的11.2.1小節中會用到這些內容。

另外,如果代碼10發現結果為AsyncRpcResult,則說明是服務提供方的異步執行,此時返回對應的CompletableFuture對象,如果返回的是正常的RpcResult結果,則使用CompletableFuture.completedFuture(result);把結果轉換為CompletableFuture對象(即同步轉異步),以便統一處理,在隨后的11.2.1小節中我們也會講到。

主站蜘蛛池模板: 彭阳县| 福贡县| 比如县| 库伦旗| 麻栗坡县| 方山县| 田阳县| 灵璧县| 随州市| 三门峡市| 安康市| 花莲市| 金湖县| 蓬溪县| 台南市| 凤城市| 徐闻县| 林西县| 洪雅县| 武宣县| 开化县| 兰坪| 唐海县| 葵青区| 怀宁县| 红桥区| 双柏县| 白城市| 邓州市| 和田市| 东阿县| 甘泉县| 鄂托克前旗| 苏尼特右旗| 陆良县| 灵川县| 平和县| 酒泉市| 绥滨县| 伊川县| 柯坪县|