天天看點

【rust-grpc-proxy】自定義metadata前言原理實踐尾語

目錄

  • 前言
  • 原理
  • 實踐
    • 目标服務
    • 生成配置
    • 運作程式
    • 測試請求
  • 尾語

前言

沒有廢話

原理

grpc可以通過metadata(中繼資料)實作類似http header的效果。

grpc底層使用http2通訊,而metadata通常會放在http2的header中傳輸,這也是本文支援的方式。

trailer 方式也能傳輸metadata,但我不常用,且處理較為麻煩,如無必要,則不支援。(絕對不承認自己懶)

實踐

目标服務

首先修改一下我們之前的echo服務,增加一個攔截器,會将我們設定的metadata回顯回來。

func metadataInterceptor() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
		md, ok := metadata.FromIncomingContext(ctx)
		header := metadata.New(map[string]string{})
		if ok {
			for k, v := range md {
				if k == "content-type" || k == "content-length" {
					continue
				}
				header.Set(k, v[0])
			}
		}
		resp, err = handler(ctx, req)
		if err != nil {
			return nil, err
		}
		err = grpc.SetHeader(ctx, header)
		return resp, err
	}
}
           

将上面的代碼加入到任何帶有反射的grpc服務中,或者用項目中的測試程式目錄是:

example/metadata/server

環境需要mac才行

cd example/metadata

//會啟動一個目标服務,并監聽1234端口
./example.sh server
           

生成配置

運作指令生成配置

//example/metadata
./example.sh config 
           

可以看到配置中的内容

[metadata_filters]
prefix = ["echo-","greet-"]
match = ["use-name","use-id"]
           
  • prefix 字首比對,配置為空則預設

    ["md-"]

  • match 完全比對

運作程式

用如下指令運作代理

//mac系統 dir:example/metadata
./rust-grpc-proxy run -c config.toml

//或者在根目錄運作
cargo run -- run -c ./example/metadata/config.toml
           

測試請求

curl --location --request GET 'http://127.0.0.1:6789/api/v1/echo/hello/get?query=666' \
--header 'echo-hello: world' \
--header 'md-hello: md-world' \
--header 'use-name: mynameiswd'
           

可以在response 的header看到 回顯内容。表明測試成功

尾語

目前基礎功能已經完成的差不了。根據計劃,之後會完善使用體驗上的内容。

繼續閱讀