日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

异步接口同步返回_Dubbo客户端异步接口的实现背景和实践

發布時間:2025/4/16 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 异步接口同步返回_Dubbo客户端异步接口的实现背景和实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鋪墊

先簡單介紹下一次完整的Dubbo調用所經歷的線程階段。幾個信息這里羅列下

  • Biz~代表業務線程,即便是業務邏輯處理所處的線程,Biz~線程池可能是業務自己創建維護,大多數的可能是系統框架自身管理的(比如web型的業務系統跑在Tomcat容器下,Biz~線程就是Tomcat維護);IO~代表網絡數據處理線程,是IO框架(比如Netty,Grizzly)創建維護,Dubbo Remoting所默認Netty實現是NioEventloopLoopGroup;另外按照Channel與IO線程的綁定關系,也可以直接把IO~看成一個可接受事件消息的Channel。像Biz和IO這樣的異步處理階段在JDK8中有個很精確地抽象描述,叫CompletionStage。
  • 大家知道,線程與線程之間做數據通信的方式是共享變量,Biz和IO兩個stage之間的數據通信是Queue,具體到Dubbo實現,在客戶端一側的實現(即上圖中用1所標注的步驟)中Biz是通過向EventLoop的LinkedBlockingQueue放置一個Task,而EventLoop有對應的Thread會不停的迭代Queue來執行Task中所包含的信息,具體代碼可以看SingleThreadEventExecutor(順便提下,Netty中默認是用無上限的LinkedBlockingQueue,在Biz的速率高于網絡速率情況下,似乎好像有Memory Leak的風險)。
  • 如上圖所示,標準的一次RPC調用經過了圖中所示的1,2,3,4的四次消息(事件)傳遞,分別是客戶端業務線程到IO線程的請求發出,服務端IO線程到業務邏輯線程的__請求接受,__服務端處理完成后由業務邏輯線程到IO線程的響應寫出,客戶端收到結果后從IO線程到業務邏輯的響應處理。除了1與4之間一般需要維護響應和請求的映射對應關系,四次的事件處理都是完全獨立的,所以一次RPC調用天然是異步的,而同步是基于異步而來。
  • 客戶端異步

    實現背景

    在Java語言(其他語言不清楚)下一次本地接口的調用可以透明地通過代理機制轉為遠程RPC的調用,大多數業務方也比較喜歡這種與本地接口類似的編程方式做遠程服務集成,所以雖然RPC內部天然是異步的,但使用Dubbo的用戶使用最廣泛的還是同步,而異步反而成為小眾的使用場景。同步的優點是編程模型更加符合業務方的“傳統”習慣,代價是在圖中的1代表的請求發出事件后需要阻塞當前的Biz~線程,一直等到4代表的響應處理后才能喚醒。在這個短則微秒級別,長則秒級的1,2,3,4處理過程中都要阻塞Biz~線程,就會消耗線程資源,增加系統資源的開銷。

    所以,客戶端異步的出發點是節省線程資源開銷,代價是需要了解下異步的使用方式:)。在同步方式下API接口的返回類型是代表著某個業務類,而當異步情況下,響應返回與請求發出是完全獨立的兩個事件,需要API接口的返回類型變為上述中說的CompletionStage才是最貼合的,這是Dubbo在異步上支持的必然異步。回到最近的Dubbo發布版,是不改變接口的情況下,需要在服務創建時注冊一個回調接口來處理響應返回事件。

    下面以示例來說。

    示例

    事件通知的示例代碼請參考:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify

    事件通知允許 Consumer 端在調用之前、調用正常返回之后或調用出現異常時,觸發 oninvoke、onreturn、onthrow 三個事件。

    可以通過在配置 Consumer 時,指定事件需要通知的方法,如:

    <bean id="demoCallback" class="com.alibaba.dubbo.samples.notify.impl.NotifyImpl" /><dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.samples.notify.api.DemoService" version="1.0.0" group="cn"><dubbo:method name="sayHello" onreturn="demoCallback.onreturn" onthrow="demoCallback.onthrow"/> </dubbo:reference>

    其中,NotifyImpl 的代碼如下:

    public class NotifyImpl implements Notify{public Map<Integer, String> ret = new HashMap<Integer, String>();public void onreturn(String name, int id) {ret.put(id, name);System.out.println("onreturn: " + name);}public void onthrow(Throwable ex, String name, int id) {System.out.println("onthrow: " + name);} }

    這里要強調一點,自定義 Notify 接口中的三個方法的參數規則如下:

    • oninvoke 方法參數與調用方法的參數相同;
    • onreturn方法第一個參數為調用方法的返回值,其余為調用方法的參數;
    • onthrow方法第一個參數為調用異常,其余為調用方法的參數。

    上述配置中,sayHello方法為同步調用,因此事件通知方法的執行也是同步執行。可以配置 async=true讓方法調用為異步,這時事件通知的方法也是異步執行的。特別強調一下,oninvoke方法不管是否異步調用,都是同步執行的。

    實踐建議

    • RPC調用后的邏輯非強依賴結果:異步回調是在客戶端非強依賴服務端的結果情況下,是適用客戶端的異步調用。
    • rx場景:自從了解到reactive的編程模型后,認為只要編程思維能夠擁抱reactive,并且業務模型的狀態機設計能做適當的調整,任何場景下都比較適用異步來解決,從而得到更好的終端響應體驗。 對于Dubbo來說,當下的異步接口模型是需要像reactive的模型接口做改進,才能使得用戶更自然地適用異步接口。

    小結

    • 客戶端異步的出發點就是請求發出和響應處理本身為兩個不同的獨立事件,響應如何被處理和在哪個線程中處理等都是不需要和請求發出事件的業務邏輯線程做耦合綁定。
    • 響應事件回調的處理邏輯在哪個線程中做處理是需要根據情況來選擇。建議,如果回調邏輯比較簡單,建議直接在IO線程中;如果包含了遠程訪問或者DB訪問等IO型的__同步__操作,建議在獨立的線程池做處理。

    總結

    以上是生活随笔為你收集整理的异步接口同步返回_Dubbo客户端异步接口的实现背景和实践的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。