gRPC為什麼使用截止時間而不是超時時間?
在 HTTP 請求中,我們傳送請求的時候,可以設定一個請求超時時間-connectTimeout,即在指定的時間內,如果請求沒有到達服務端,為了避免客戶端一直進行不必要的等待,就會丟擲一個請求超時異常。
但是在微服務系統中,我們卻很少設定請求超時時間,一般都是用另外一個概念代替,那就是請求截止時間。
這是什麼原因呢?今天我們就來簡單聊一聊這個話題。
在微服務中我們客戶端的請求在服務端往往會有比較複雜的鏈條,我想起來 Spring Cloud Sleuth 官方給的一個請求鏈路追蹤的圖,我們直接拿來看下:
這張圖中,請求從客戶端發起之後,在服務端一共經歷了四個 SERVICE,對於這樣的請求,如果我們還是按照之前傳送普通 HTTP 請求的方式,設定一個 connectTimeout 顯然是不夠的。
我舉個例子:
假設我們傳送一個請求,為該請求設定 connectTimeout 為 5s,那麼這個時間只對第一個服務 SERVICE1 有效,也就是請求在 5s 之內沒有到達 SERVICE1,那麼就會丟擲連線超時異常;請求如果在 5s 之內到達 SERVICE1,那麼就不會丟擲異常,但是!!!,請求到達 SERVICE1 並不意味著請求結束,後面從 SERVICE1 到 SERVICE2,從 SERVICE2 到 SERVICE3,從 SERVICE3 到 SERVICE4,還有四個 HTTP 請求待處理,這些請求超時了怎麼辦?很明顯,connectTimeout 屬性對於後面幾個請求就鞭長莫及了。
所以,對於這種場景,我們一般使用截止時間來處理。
截止時間相當於設定整個請求生命週期的時間,也就是這個請求,我要多久拿到結果。很明顯,這個時間應該在客戶端發起請求的時候設定。
gRPC 中提供了對應的方法,我們可以非常方便的設定請求的截止時間 DeadLineTime,如下:
public class LoginClient {
public static void main(String[] args) throws InterruptedException {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext()
.build();
LoginServiceGrpc.LoginServiceStub stub = LoginServiceGrpc.newStub(channel).withDeadline(Deadline.after(3, TimeUnit.SECONDS));
login(stub);
}
private static void login(LoginServiceGrpc.LoginServiceStub stub) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
stub.login(LoginBody.newBuilder().setUsername("javaboy").setPassword("123").build(), new StreamObserver<LoginResponse>() {
@Override
public void onNext(LoginResponse loginResponse) {
System.out.println("loginResponse.getToken() = " + loginResponse.getToken());
}
@Override
public void onError(Throwable throwable) {
System.out.println("throwable = " + throwable);
}
@Override
public void onCompleted() {
countDownLatch.countDown();
}
});
countDownLatch.await();
}
}
服務端透過 Thread.sleep 做個簡單的休眠就行了,超時之後,客戶端的 onError 方法會被觸發,丟擲如下異常:
throwable = io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after 2.939621462s. [closed=[], open=[[buffered_nanos=285550823, remote_addr=localhost/127.0.0.1:50051]]]
好啦,一個簡單的小細節,感興趣的小夥伴不妨去試試啦~
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2937810/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 為jQuery的$.ajax設定超時時間jQuery
- 帝國cms為什麼釋出時間比實際時間相差8個小時?
- 上班時間做什麼
- 時間戳轉化為時間格式時間戳
- 幽默:程式設計是10%時間用於寫程式碼而90%時間用於理解為什麼不工作 -mariofusco程式設計
- 不同使用者,不同的session超時時間Session
- win10時間線有什麼用_win10時間線怎麼使用Win10
- session超時時間的設定Session
- weblogic設定超時時間Web
- 時間日期字串轉換為時間物件字串物件
- 我什麼時候應該使用TreeMap 而不是 PriorityQueue?反之亦然?
- 查詢時若時間為空,開始時間取今天的零點,結束時間取當前時間
- HttpClient設定聯網超時時間HTTPclient
- C# UdpClient 設定超時時間C#UDPclient
- 修改CentOS伺服器時間為北京時間CentOS伺服器
- 如何將時間字串轉換為時間物件字串物件
- javascript將時間物件轉換為時間戳JavaScript物件時間戳
- 安卓核心時間使用的是UTC時間安卓
- MySQL時間戳、時間MySql時間戳
- 為什麼“敏捷”會浪費這麼多時間? - Reddit敏捷
- 為什麼你的專案要花這麼長時間?
- MySQL為欄位新增預設時間(插入時間)MySql
- 為什麼程式設計師不擅長估算時間程式設計師
- php 和 nginx 的幾個超時時間PHPNginx
- System.Data.SqlClient.SqlException 超時時間已到SQLclientException
- mysql時間操作(時間差和時間戳和時間字串的互轉)MySql時間戳字串
- js怎麼將伺服器GMT時間轉為中國標準時間JS伺服器
- ngnix使用超時響應時間配置避坑一例
- Linux時間設定系統時間、硬體時間和時間服務Linux
- context裡的超時時間是怎麼在微服務之間傳遞的Context微服務
- python之為函式執行設定超時時間(允許函式執行的最大時間)Python函式
- JS自動生成24小時時間區間,時間跨度為60或30分鐘JS
- 將時間戳轉換為時間例項程式碼時間戳
- UTC格式時間轉換為當地時間程式碼
- js將時間日期物件轉換為時間日期字元JS物件字元
- Linux使用ntp時間伺服器同步時間Linux伺服器
- beego 什麼時候支援grpcGoRPC
- 長時間工作意味著什麼?