溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Dubbo異步處理

發布時間:2021-10-19 16:28:44 來源:億速云 閱讀:189 作者:iii 欄目:web開發

這篇文章主要介紹“怎么使用Dubbo異步處理”,在日常操作中,相信很多人在怎么使用Dubbo異步處理問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Dubbo異步處理”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

異步調用

我們平常大部分都是使用 Dubbo 的同步調用,即調用 Dubbo 請求之后,調用線程將會阻塞,直到服務提供者返回結果。

那相反,Dubbo 異步調用就不會阻塞調用線程,那么在服務提供者返回結果這段時間,我們就可以執行其他業務邏輯。

下面我們從代碼示例,來學習一下如何使用 Dubbo 異步調用。

PS:下面例子 Dubbo 版本為 2.7。

第一種方式

Dubbo 異步調用是針對方法級別,所以我們需要對引用接口中指定方法做一些專門的配置。

異步調用配置其實與普通 xml服務引用配置類似,只不過我們還需要增加一個 dubbo:method將指定方法配置成異步調用。

示例 xml 配置如下:

<dubbo:reference id="asyncService" interface="org.apache.dubbo.samples.governance.api.AsyncService">       <dubbo:method name="sayHello" async="true" /> </dubbo:reference>

服務引用配置完成之后,此時如果直接調用這個方法,將會立即返回 null,內部將會異步執行服務端調用邏輯。

// 此調用會立即返回null String world = asyncService.sayHello("world");

// 畫個時序圖

如果我們需要獲取服務提供者返回的結果,那么此時需要借助 RpcContext。這個類是 Dubbo 中專門用于保存 「RPC」  調用過程中一些關鍵信息。

因此我們可以借助這個類可以獲取到 「RPC」 很多信息,這次我們主要使用下面的方法獲取 CompletableFuture。

RpcContext.getContext().getCompletableFuture()

CompletableFuture 是 JDK1.8 之后提供的異步任務增強類,我們可以直接調用其 get 方法直接獲取返回結果。

// 此調用會立即返回null String world = asyncService.sayHello("world"); // 拿到調用的Future引用,當結果返回后,會被通知和設置到此Future CompletableFuture<String> helloFuture = RpcContext.getContext().getCompletableFuture(); helloFuture.get();

這里需要注意一點。調用get 方法之后,線程就會被阻塞,「直到服務端返回結果或者服務調用超時」。

另外如果不想線程被阻塞,我們可以使用 whenComplete,添加回調方法,然后異步處理返回結果。

// 此調用會立即返回null String world = asyncService.sayHello("world"); // 拿到調用的Future引用,當結果返回后,會被通知和設置到此Future CompletableFuture<String> helloFuture = RpcContext.getContext().getCompletableFuture(); // 為Future添加回調 helloFuture.whenComplete((retValue, exception) -> {     if (exception == null) {         System.out.println("return value: " + retValue);     } else {         exception.printStackTrace();     } });

從上面的例子我們可以看到, Dubbo 消費端異步調用借助了JDK 提供的  CompletableFuture,這個類非常強大,提供的方法也非常多。

小黑哥之前寫過一篇文章,比較完整的介紹了 CompletableFuture的用法,感興趣可以深入學習一下。

// TODO 文章

上面的方式我們使用 xml引用服務,不過現在很多同學應該直接使用 Dubbo 注解引用服務。

如果想直接使用注解方式,其實也非常簡單,只要使用 @Method注解即可。

配置方法如下:

@Reference(interfaceClass = AsyncService.class,         timeout = 1000,         methods = {@Method(name = "sayHello", async = true)}) private AsyncService asyncService;

第二種方式

第一種方式我們還需要額外修改 Dubbo 相關配置,相對來說比較繁瑣。那第二種方式就不需要做額外配置了,它只要使用  RpcContext#asyncCall就可以直接完成異步調用。

示例代碼如下:

// 使用  asyncCall 異步調用 CompletableFuture<String> f = RpcContext.getContext().asyncCall(() -> asyncService.sayHello("async call request")); // get 將會一直阻塞到服務端返回,或者直到服務調用超時 System.out.println("async call returned: " + f.get());  // 異步調用,不關心服務端返回 RpcContext.getContext().asyncCall(() -> {     asyncService.sayHello("one way call request1"); });

這種方式返回依然是 CompletableFuture對象,操作方式就如同第一種方式。

第三種方式

終于到了最后一種方式了,這種方式與上面兩種方式都不太一樣,其完全不需要借助RpcContext就可以完成,開發流程與普通 Dubbo 服務一樣。

首先需要服務提供者事先定義 CompletableFuture 簽名的服務:

public interface AsyncService {     CompletableFuture<String> sayHello(String name); }

「注意接口的返回類型是 CompletableFuture?!?/string>

服務端接口實現邏輯如下:

public class AsyncServiceImpl implements AsyncService {     private static Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);      @Override     public CompletableFuture<String> sayHello(String name) {         return CompletableFuture.supplyAsync(() -> {             try {                 Thread.sleep(10000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             return "async response from provider.";         });     }  }

服務端需要使用 CompletableFuture 完成業務邏輯。

消費端這時就不需要借助了 RpcContext,可以直接調用服務提供者。

// 調用直接返回CompletableFuture CompletableFuture<String> future = asyncService.sayHello("async call request"); // 增加回調 future.whenComplete((v, t) -> {     if (t != null) {         t.printStackTrace();     } else {         System.out.println("Response: " + v);     } }); // 早于結果輸出 System.out.println("Executed before response return.")

這種方式對于調用者來就比較方便,無需引入其他對象,可以像使用同步的方式使用異步調用。

其他參數

上面介紹了三種的 Dubbo 異步調用的使用方式,下面主要介紹一下異步調用涉及其他參數。

sent

我們可以在 dubbo:method 設置:

<dubbo:method name="findFoo" async="true" sent="true" />

也可以在注解中設置:

@Reference(interfaceClass = XXX.class,         version = AnnotationConstants.VERSION,         timeout = 1000,         methods = {@Method(name = "greeting", timeout = 3000, retries = 1, sent = false)})

默認情況下sent=false, Dubbo 將會把消息放入 IO 隊列,然后立刻返回。那這時如果宕機,消息就有可能沒有發送給服務端。

那如果我們將其設置成 sent=true,Dubbo 將會等待消息發送發出才會返回,否則將會拋出異常。

return

Dubbo 異步調用默認將會創建 Future 對象,然后設置到 RpcContext 中。那我們如果不關心返回值,只想單純的異步執行,那我們可以配置  return="false",以此減少 Future 對象的創建和管理成本。

<dubbo:method name="findFoo" async="true" return="false" />

到此,關于“怎么使用Dubbo異步處理”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女