- 深度剖析ApacheDubbo核心技術內幕
- 翟陸續
- 1168字
- 2020-03-02 16:12:20
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小節中我們也會講到。
- SPSS數據挖掘與案例分析應用實踐
- Microsoft Application Virtualization Cookbook
- Mastering Ember.js
- Python網絡爬蟲從入門到實踐(第2版)
- 程序員考試案例梳理、真題透解與強化訓練
- DevOps Automation Cookbook
- 學Python也可以這么有趣
- Scientific Computing with Scala
- Python語言實用教程
- Unity 3D/2D移動開發實戰教程
- Qt5 C++ GUI Programming Cookbook
- Nagios Core Administration Cookbook(Second Edition)
- Learning Python Data Visualization
- INSTANT Apache ServiceMix How-to
- Visual C++從入門到精通(第2版)