gRPC 介紹

在微服務的架構下,服務跟服務之間的溝通常見的有幾個方式

  • 使用阿里巴巴開源的 RPC 協定 Dubbo
  • 使用 Google 開源的 gRPC
  • 使用 Restful Api 方式
  • 使用 Middleware 如:MQ

今天要跟大家介紹的是 gRPC,一樣我們先看gRPC官網上他是怎麼介紹他自己的。

gRPC是可以在任何環境中運行的現代開源高性能RPC框架。它可以通過可插拔的支持來有效地連接數據中心內和跨數據中心的服務,以實現負載平衡,跟踪,運行狀況檢查和身份驗證。它也適用於分佈式計算的最後一英里,以將設備,移動應用程序和瀏覽器連接到後端服務。

接下來我會開始介紹如何在專案中導入 gRPC 的框架,並且套到範例之中。

Quick Start

gRPC 客戶端與服務器端中有4種數據交換模式,分別如下

  • 簡易模式
  • 服務器端 streaming 模式
  • 客戶端 streaming 模式
  • 雙向 streaming 模式
    接下來我們的例子會分別介紹 簡易模式雙向 streaming 模式

基礎建置

  • build.gradle 加入 dependencies 與 設置 proto 檔案生成出的檔案路徑位置
1
2
3
4
5
6
dependencies {
implementation 'io.grpc:grpc-netty-shaded:1.22.1'
implementation 'io.grpc:grpc-protobuf:1.22.1'
implementation 'io.grpc:grpc-stub:1.22.1'
implementation 'io.github.lognet:grpc-spring-boot-starter:3.3.0'
}

完整請參考如下:

  • 建立 proto 檔案

src/proto/base 建立 GpCommon.proto

src/proto/lotcenter 建立 GameServer.proto

  • 使用 gradle 指令,生成 java 檔案
    1
    2
    3
    4
    ### 清除產生的檔案
    $ gradle cleanProtoGen
    ### 產生檔案
    $ gradle generateProto

產生的檔案結構如下:

程式撰寫

因為我們使用 io.github.lognet:grpc-spring-boot-starter 所以可以直接使用 annotation

  • GameServerService.java
  • 特別說明
    • 這邊需要特別說明的就是,當使用 streaming 時,需要客製化將 StreamObserver 紀錄下來,這樣推播訊息時,才能正確推播出去。
    • 這邊可以注意到,在使用推播時,需要加上 synchronized,不然同一時間進行推播時會出現 java.lang.IllegalStateException: Stream 3 sent too many headers EOS: false,可參考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 推播遊戲狀態
*
* @param gameConfigId
* @param gameStatusBroadcastRes
*/
public void pushGameStatus(Integer gameConfigId, GameStatusBroadcastRes gameStatusBroadcastRes) {

log.debug(String.format("gameConfigId: %s, gameStatusBroadcastRes: %s", gameConfigId, gameStatusBroadcastRes));

// 推播遊戲狀態(所有)
pushAllGameStatus(gameStatusBroadcastRes);

// 推播遊戲狀態(單一)
List<StreamObserver<GameStatusBroadcastRes>> gameStatusResList = gameStatusMap.get(gameConfigId);
if (!CollectionUtils.isEmpty(gameStatusResList)) {
for(StreamObserver<GameStatusBroadcastRes> responseObserver:gameStatusResList) {
synchronized (responseObserver) {
responseObserver.onNext(gameStatusBroadcastRes);
}
}
}
}
  • 測試

今天先到這邊了,如果有其他問題,歡迎寄信討論!謝謝!

Reference

gRPC
gRPC Example
LogNet

謝謝您的支持與鼓勵

Ads