gRPC攔截器那點事,希望幫到你
- 2019 年 10 月 4 日
- 筆記
上一篇介紹了gRPC的介面認證,我們客戶端需要實現gRPC提供的介面,然後在服務端業務介面實現中通過metadata獲取認證資訊,進行判斷,那麼當我們有幾十個,幾百個業務介面時,如果都在介面實現中去做,那將是一個噩夢,也不符合DRY(Don't Repeat Yourself)原則,今天一起來看看如何通過gRPC的攔截器做到統一介面認證工作
初識gRPC攔截器
- gRPC在grpc包中定義了一個變數,如下,這個變數叫做UnaryServerInterceptor(一元服務攔截器),

- 其類型是一個函數,這個函數有,4個入參,兩個出參,介紹如下
- ctx context.Context 上下文
- req interface{} 用戶請求的參數
- info UnaryServerInfo RPC 方法的所有資訊,定義如下

- handler UnaryHandler RPC方法本身
- resp interface{} RPC方法執行結果

如何使用
- 首先定義一個攔截器

- 在服務端啟動時將攔截器添加進去

- 如上就是服務端使用攔截器的所有步驟,客戶端在訪問服務端時就會被攔截
如何添加多個攔截器
- 有人說我看上面程式碼grpc.NewServer是一個可變參數,我傳多個不就好了嗎?真的是這樣嗎,我們來試試,程式碼如下我們添加了兩個攔截器

- 很遺憾,服務端啟動失敗,報錯資訊如下,什麼含義呢,意思是說,這個一元服務攔截器只能設置一個,不能重複,其實從名字就能看出,一元攔截器,就是說只能設置一個攔截器,gRPC有意的阻止攔截器鏈的形式
panic: The unary server interceptor was already set and may not be reset. [recovered] panic: The unary server interceptor was already set and may not be reset.
- 那我們如果真的需要攔截器鏈,該如何配置呢,核心思想是遞歸,程式碼如下:

- github上已經有這麼一個項目,如下
- https://github.com/grpc-ecosystem/go-grpc-middleware
- 這個項目提供了攔截器的interceptor鏈式的功能,還有其它一些功能,大家可以去學習學習。
gRPC還有哪些攔截器
統一在grpc包下,其他攔截器如下
type UnaryClientInterceptor
這是一個客戶端上的攔截器,在客戶端真正發起調用之前,進行攔截,這是一個實驗性的api,這是gRPC官方的說法
type StreamClientInterceptor
在流式客戶端調用時,通過攔截clientstream的創建,返回一個自定義的clientstream,可以做一些額外的操作,這是一個實驗性的api,這是gRPC官方的說法
type UnaryServerInterceptor (就是上面我們demo中的攔截器)
type StreamServerInterceptor
攔截伺服器上流式rpc的執行
gRPC的攔截分類
- 按功能來分
- 一元攔截器 UnaryInterceptor
- 流式攔截器 StreamInterceptor
- 按端來分
- 客戶端攔截器 ClientInterceptor
- 服務端攔截器 ServerInterceptor
- 大家平時使用時靈活使用即可,慢慢的就會融會貫通