問題引入
有時遠程調用的服務執行時間太慢,消費端不想等待,這該怎麼辦?沒事,Dubbo 給我們提供了一個超時機制,超過指定的時間,直接返回一個超時異常即可。
測試
下面我們來測試一下,在提供者中我們讓其睡眠兩秒再返回,消費者一切設置正常。
@Component
@Service
public class NameServiceImpl implements NameService {
@Override
public String updateName(String name) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "修改後的名稱:" + name;
}
}
然後我們在瀏覽器輸入 http://localhost:8081/change/HelloDubbo,讓消費者遠程調用提供者提供的服務。
提供者顯示正常,而消費者報錯:
咦,有的同學可能會奇怪了,我都還沒設置超時呢,怎麼就直接報錯了?事實上,Dubbo 對超時的缺省配置爲1s,即每個接口的返回時間不得超過1s,否則會拋出異常。
下面我們改一下需求,這個接口的返回時間在3s之內都可以被容忍(天天報錯,受不了了!),那麼我們的設置應該怎麼改?
在消費者中添加如下配置即可。
#設置全局超時控制爲3s
dubbo.consumer.timeout=3000
現在我們再遠程調用提供者提供的服務,發現可以返回了,說明我們配置的超時設置生效了。
超時針對提供者還是針對消費者
我們接下來考慮一個問題,超時是針對提供者呢,還是針對消費者呢?
超時是針對消費者的,其實 Dubbo 使用的是 NIO 模式,消費端發起請求後會得到一個 ResponseFuture,然後消費端一直輪詢這個 ResponseFuture 直至超時或者收到服務端的返回結果。在上面我們的測試中大家也能發現,在超時之後,消費者直接拋出異常,但提供者照樣沒事似地繼續運行,所以顯然超時是針對消費者的。
超時需要在哪裏設置?
有讀者可能會說,咦,博主你之前不是說超時是針對消費者的嗎,那肯定得在消費者上設置了!這話說對也不對,說不對也對。爲什麼呢?
Dubbo 在提供者和消費者中都可以進行相應的設置,但是如果兩者都進行設置了,那麼就以消費者中的設置爲準。
但是我們最好還是在提供者進行相應的配置,爲啥?
首先,作爲服務的提供者,肯定要比消費者更清楚服務性能參數。再者,如果我們沒有配置消費者,會使用提供者的設置作爲缺省值。
超時設置的優先級
針對控制的粒度,Dubbo 既支持了接口級別也支持方法級別,還支持全局級別,我們可以根據實際情況精確控制每個方法的超時時間。這裏對超時設置的優先級做個總結,最終的優先級如下,從上往下優先級遞減。
- 客戶端方法級
- 服務端方法級
- 客戶端接口級
- 服務端接口級
- 客戶端全局級
- 服務端全局級