Dubbo异步调用
????????Dubbo不只提供了堵塞式的的同步調用,同時提供了異步調用的方式。這種方式主要應用于提供者接口響應耗時明顯,消費者端可以利用調用接口的時間去做一些其他的接口調用,利用Future 模式來異步等待和獲取結果即可。這種方式可以大大的提升消費者端的利用率。 目前這種方式可以通過XML的方式進行引入。
1、異步調用實現
(1)為了能夠模擬等待,通過 int timeToWait參數,標明需要休眠多少毫秒后才會進行返回。
String sayHello(String name, int timeToWait);
(2)接口實現 為了模擬調用耗時 可以讓線程等待一段時間
(3)在消費者端,配置異步調用 注意消費端默認超時時間1000毫秒 如果提供端耗時大于1000毫秒會出現超時
? ?可以通過改變消費端的超時時間 通過timeout屬性設置即可單位毫秒
<dubbo:reference id="helloService" interface="com.lagou.service.HelloService"><!--添加異步調用方式,注解方式不支持--><dubbo:method name="sayHello" async="true" /> </dubbo:reference>(4)測試,我們休眠100毫秒,然后再去進行獲取結果。方法在同步調用時的返回值是空,我們可以通過RpcContext.getContext().getFuture() 來進行獲取Future對象來進行后續的結果等待操作。
package com.lagou;import com.lagou.bean.ConsumerComponent; import com.lagou.service.HelloService; import com.sun.org.apache.xpath.internal.functions.FuncTrue; import org.apache.dubbo.rpc.RpcContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import java.io.IOException; import java.util.concurrent.Future;public class XMLConsumerMain {public static void main(String[] args) throws IOException, InterruptedException {ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("consumer.xml");HelloService service = app.getBean(HelloService.class);while (true) {System.in.read();try {String hello = service.sayHello("world", 100);// 利用Future 模式來獲取Future<Object> future = RpcContext.getContext().getFuture();System.out.println("result :" + hello);System.out.println("future result:"+future.get());} catch (Exception e) {e.printStackTrace();}}}}2、異步調用特殊說明
????????需要特別說明的是,該方式的使用,請確保dubbo的版本在2.5.4及以后的版本使用。 原因在于在2.5.3及之前的版本使用的時候,會出現異步狀態傳遞問題。
????????比如我們的服務調用關系是A -> B -> C , 這時候如果A向B發起了異步請求,在錯誤的版本時,B向C發起的請求也會連帶的產生異步請求。這是因為在底層實現層面,他是通過RPCContext 中的attachment 實現的。在A向B發起異步請求時,會在attachment 中增加一個異步標示字段來表明異步等待結果。B在接受到A中的請求時,會通過該字段來判斷是否是異步處理。但是由于值傳遞問題,B向C發起時同樣會將該值進行傳遞,導致C誤以為需要異步結果,導致返回空。這個問題在2.5.4及以后的版本進行了修正。
總結
- 上一篇: 实战知识点(一):CSS和JS部分知识点
- 下一篇: Java九阳真经论述及愿景