自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

gRPC為什么使用截止時(shí)間而不是超時(shí)時(shí)間?

開(kāi)發(fā) 前端
截止時(shí)間相當(dāng)于設(shè)置整個(gè)請(qǐng)求生命周期的時(shí)間,也就是這個(gè)請(qǐng)求,我要多久拿到結(jié)果。很明顯,這個(gè)時(shí)間應(yīng)該在客戶端發(fā)起請(qǐng)求的時(shí)候設(shè)置。

在 HTTP 請(qǐng)求中,我們發(fā)送請(qǐng)求的時(shí)候,可以設(shè)置一個(gè)請(qǐng)求超時(shí)時(shí)間-connectTimeout,即在指定的時(shí)間內(nèi),如果請(qǐng)求沒(méi)有到達(dá)服務(wù)端,為了避免客戶端一直進(jìn)行不必要的等待,就會(huì)拋出一個(gè)請(qǐng)求超時(shí)異常。

但是在微服務(wù)系統(tǒng)中,我們卻很少設(shè)置請(qǐng)求超時(shí)時(shí)間,一般都是用另外一個(gè)概念代替,那就是請(qǐng)求截止時(shí)間。

這是什么原因呢?今天我們就來(lái)簡(jiǎn)單聊一聊這個(gè)話題。

在微服務(wù)中我們客戶端的請(qǐng)求在服務(wù)端往往會(huì)有比較復(fù)雜的鏈條,我想起來(lái) Spring Cloud Sleuth 官方給的一個(gè)請(qǐng)求鏈路追蹤的圖,我們直接拿來(lái)看下:

圖片

這張圖中,請(qǐng)求從客戶端發(fā)起之后,在服務(wù)端一共經(jīng)歷了四個(gè) SERVICE,對(duì)于這樣的請(qǐng)求,如果我們還是按照之前發(fā)送普通 HTTP 請(qǐng)求的方式,設(shè)置一個(gè) connectTimeout 顯然是不夠的。

我舉個(gè)例子:

假設(shè)我們發(fā)送一個(gè)請(qǐng)求,為該請(qǐng)求設(shè)置 connectTimeout 為 5s,那么這個(gè)時(shí)間只對(duì)第一個(gè)服務(wù) SERVICE1 有效,也就是請(qǐng)求在 5s 之內(nèi)沒(méi)有到達(dá) SERVICE1,那么就會(huì)拋出連接超時(shí)異常;請(qǐng)求如果在 5s 之內(nèi)到達(dá) SERVICE1,那么就不會(huì)拋出異常,但是?。?!,請(qǐng)求到達(dá) SERVICE1 并不意味著請(qǐng)求結(jié)束,后面從 SERVICE1 到 SERVICE2,從 SERVICE2 到 SERVICE3,從 SERVICE3 到 SERVICE4,還有四個(gè) HTTP 請(qǐng)求待處理,這些請(qǐng)求超時(shí)了怎么辦?很明顯,connectTimeout 屬性對(duì)于后面幾個(gè)請(qǐng)求就鞭長(zhǎng)莫及了。

所以,對(duì)于這種場(chǎng)景,我們一般使用截止時(shí)間來(lái)處理。

截止時(shí)間相當(dāng)于設(shè)置整個(gè)請(qǐng)求生命周期的時(shí)間,也就是這個(gè)請(qǐng)求,我要多久拿到結(jié)果。很明顯,這個(gè)時(shí)間應(yīng)該在客戶端發(fā)起請(qǐng)求的時(shí)候設(shè)置。

gRPC 中提供了對(duì)應(yīng)的方法,我們可以非常方便的設(shè)置請(qǐng)求的截止時(shí)間 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();
}
}

服務(wù)端通過(guò) Thread.sleep 做個(gè)簡(jiǎn)單的休眠就行了,超時(shí)之后,客戶端的 onError 方法會(huì)被觸發(fā),拋出如下異常:

throwable = io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after 2.939621462s. [closed=[], open=[[buffered_nanos=285550823, remote_addr=localhost/127.0.0.1:50051]]]

好啦,一個(gè)簡(jiǎn)單的小細(xì)節(jié),感興趣的小伙伴不妨去試試?yán)病?/p>

責(zé)任編輯:武曉燕 來(lái)源: 江南一點(diǎn)雨
相關(guān)推薦

2013-03-25 10:14:18

NginxApache

2020-09-15 09:23:19

C++WindowsC#

2021-02-26 05:30:25

元素For-Each代碼

2021-03-26 11:50:28

Linuxexals

2021-06-30 12:47:12

標(biāo)簽HTML分辨率

2019-04-19 11:56:48

框架AI開(kāi)發(fā)

2016-09-19 09:15:49

Windows 10鎖屏超時(shí)

2020-02-20 09:55:46

LinuxPython數(shù)據(jù)

2012-10-10 16:52:21

CentOSDebianUbuntu

2021-08-14 09:04:58

TypeScriptJavaScript開(kāi)發(fā)

2021-10-30 19:57:00

HTTP2 HTTP

2017-09-11 19:58:06

PostgreSQLMySQL數(shù)據(jù)庫(kù)

2020-06-02 14:17:55

QWER排列鍵盤(pán)打印機(jī)

2025-02-12 08:47:07

SpringAPI接口

2020-07-24 09:20:44

MapObject前端

2023-11-02 08:20:54

SocketZygoteAndroid

2025-03-04 00:25:55

Go開(kāi)發(fā)者切片

2024-06-24 00:00:00

AVIFJPEG圖像格式

2023-09-29 11:50:10

接口編程代碼

2022-11-14 07:52:14

時(shí)間序列數(shù)據(jù)庫(kù)CPU
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)