成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

gRPC 中的異常該如何處理?

開發 項目管理
我們之前寫過一個登錄的案例,在之前的案例中,如果用戶在登錄時輸入了錯誤的用戶名密碼的話,那么我們是通過一個普通的數據流返回異常信息,其實,對于異常信息,我們可以通過專門的異常通道來寫回到客戶端。

今天來和小伙伴們聊一聊該如何處理 gRPC 中遇到的異常。

在之前的幾篇文章中,其實我們也遇到過異常問題,只是當時沒有和小伙伴們細說,只是囫圇吞棗寫了一個案例而已,今天我們就來把這個話題跟小伙伴們仔細捋一捋。

我們之前寫過一個登錄的案例,在之前的案例中,如果用戶在登錄時輸入了錯誤的用戶名密碼的話,那么我們是通過一個普通的數據流返回異常信息,其實,對于異常信息,我們可以通過專門的異常通道來寫回到客戶端。

1. 服務端處理異常

先來看看服務端如何處理異常。

還是以我們之前的 gRPC 登錄案例為例,我們修改服務端的登錄邏輯如下(完整代碼小伙伴們可以參考之前的 手把手教大家在 gRPC 中使用 JWT 完成身份校驗 一文):

public class LoginServiceImpl extends LoginServiceGrpc.LoginServiceImplBase {
@Override
public void login(LoginBody request, StreamObserver<LoginResponse> responseObserver) {
String username = request.getUsername();
String password = request.getPassword();
if ("javaboy".equals(username) && "123".equals(password)) {
System.out.println("login success");
//登錄成功
String jwtToken = Jwts.builder().setSubject(username).signWith(AuthConstant.JWT_KEY).compact();
responseObserver.onNext(LoginResponse.newBuilder().setToken(jwtToken).build());
responseObserver.onCompleted();
}else{
System.out.println("login error");
//登錄失敗
responseObserver.onError(Status.UNAUTHENTICATED.withDescription("login error").asException());
}
}
}

小伙伴們看到,在登錄失敗時我們通過 responseObserver.onError 方法將異常信息寫回到客戶端。這個方法的參數是一個 Throwable 對象,對于這個對象,在 Status 這個枚舉類中定義了一些常見的值,分別如下:

  • OK(0):請求成功。
  • CANCELLED(1):操作被取消。
  • UNKNOWN(2):未知錯誤。
  • INVALID_ARGUMENT(3):客戶端給了無效的請求參數。
  • DEADLINE_EXCEEDED(4):請求超過了截止時間。
  • NOT_FOUND(5):請求資源未找到。
  • ALREADY_EXISTS(6):添加的內容已經存在。
  • PERMISSION_DENIED(7):請求權限不足。
  • RESOURCE_EXHAUSTED(8):資源耗盡。
  • FAILED_PRECONDITION(9):服務端上為準備好。
  • ABORTED(10):請求被中止。
  • OUT_OF_RANGE(11):請求超出范圍。
  • UNIMPLEMENTED(12):未實現的操作。
  • INTERNAL(13):服務內部錯誤。
  • UNAVAILABLE(14):服務不可用。
  • DATA_LOSS(15):數據丟失或者損毀。
  • UNAUTHENTICATED(16):請求未認證。

系統默認給出的請求類型大致上就這些。當然,如果這些并不能滿足你的需求,我們也可以擴展這個枚舉類。

2. 客戶端處理異常

當服務端給出異常信息之后,客戶端的處理分為兩種情況。

2.1 異步請求

如果客戶端是異步請求,則直接在異常回調中處理即可,如下:

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("1234").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();
}
}

小伙伴們看到,直接在 onError 回到中處理異常即可。

2.2 同步請求

如果客戶端請求是同步阻塞請求,那么就要通過異常捕獲的方式獲取服務端返回的異常信息了,如下:

public class LoginClient2 {
public static void main(String[] args) throws InterruptedException {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext()
.build();
LoginServiceGrpc.LoginServiceBlockingStub stub = LoginServiceGrpc.newBlockingStub(channel).withDeadline(Deadline.after(3, TimeUnit.SECONDS));
login(stub);
}

private static void login(LoginServiceGrpc.LoginServiceBlockingStub stub) throws InterruptedException {
try {
LoginResponse resp = stub.login(LoginBody.newBuilder().setUsername("javaboy").setPassword("1234").build());
System.out.println("resp.getToken() = " + resp.getToken());
} catch (Exception e) {
System.out.println("e.getMessage() = " + e.getMessage());
}
}
}

同步阻塞請求就通過異常捕獲去獲取服務端返回的異常信息即可。

3. 題外話

最后,再來和小伙伴們說一個提高 gRPC 數據傳輸效率的小技巧,那就是傳輸的數據可以使用 gzip 進行壓縮。

具體處理方式就是在客戶端調用 withCompression 方法指定數據壓縮,如下:

public class LoginClient2 {
public static void main(String[] args) throws InterruptedException {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext()
.build();
LoginServiceGrpc.LoginServiceBlockingStub stub = LoginServiceGrpc.newBlockingStub(channel).withDeadline(Deadline.after(3, TimeUnit.SECONDS));
login(stub);
}

private static void login(LoginServiceGrpc.LoginServiceBlockingStub stub) throws InterruptedException {
try {
LoginResponse resp = stub.withCompression("gzip").login(LoginBody.newBuilder().setUsername("javaboy").setPassword("123").build());
System.out.println("resp.getToken() = " + resp.getToken());
} catch (Exception e) {
System.out.println("e.getMessage() = " + e.getMessage());
}
}
}

好啦,一個關于 gRPC 的小小知識點~

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2023-02-02 08:56:25

線程池線程submit

2024-08-29 08:54:35

2010-02-23 17:12:01

WCF字符串

2022-04-12 07:32:40

引擎模式Spring策略模式

2025-03-31 08:04:50

MySQLCPU內存

2012-07-03 11:18:20

運維disable tab

2017-05-26 11:32:44

程序應用測試

2018-11-21 12:27:21

JavaScript 貨幣值區域

2019-09-20 08:38:51

Python編程語言Java

2012-11-14 14:07:23

Mysql

2018-01-24 19:59:03

數據庫Oracle壞塊

2011-04-11 17:10:16

Oracle

2019-11-08 08:00:00

ASP .NETASP .NET Cocookie

2010-08-26 12:12:19

LMHOSTS文件

2021-08-18 08:20:14

SQL除數統計

2012-07-30 09:35:10

項目管理

2019-05-09 15:31:23

攻擊服務器安全

2019-08-15 10:20:19

云計算技術安全

2011-04-29 09:56:13

一體機傳真件

2021-03-24 10:40:26

Python垃圾語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产99 | 欧美日韩高清 | 99精品99| 成人免费视频一区二区 | 国产精品成人一区 | 欧美精品在线观看 | 亚洲精品久久久久久久久久久 | 福利片一区二区 | 欧美国产激情二区三区 | 乱一性一乱一交一视频a∨ 色爱av | 亚洲视频精品 | 精品欧美一区二区在线观看欧美熟 | 日本精品视频一区二区三区四区 | 免费性视频 | 亚洲国产一区二区三区在线观看 | 91视频.| 成人免费xxxxx在线视频 | 久久精品久久综合 | 99精品电影| 国产精品99久久久久久久vr | 中文字幕福利视频 | 亚洲91精品 | av在线免费看网址 | 999免费网站 | 亚洲精品福利在线 | 欧美日韩一区二区三区四区 | 国产91丝袜在线播放 | 国产乱人伦 | 亚洲精品久久久久久国产精华液 | 精品久久久久久久久久久久久久 | 亚洲成av人影片在线观看 | 国产乱码精品1区2区3区 | 日韩欧美国产精品 | 亚洲精品乱码久久久久久按摩 | 国产精品123区 | 欧美三级视频 | 精品视频国产 | 综合五月婷 | 国产乱码精品一区二区三区五月婷 | 久久久久久中文字幕 | 久久国产精品一区 |