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的攔截分類

  • 按功能來分
  1. 一元攔截器 UnaryInterceptor
  2. 流式攔截器 StreamInterceptor
  • 按端來分
  1. 客戶端攔截器 ClientInterceptor
  2. 服務端攔截器 ServerInterceptor
  • 大家平時使用時靈活使用即可,慢慢的就會融會貫通