目錄
- 前言
- 原理
- 實踐
-
- 目标服務
- 生成配置
- 運作程式
- 測試請求
- 尾語
前言
沒有廢話
原理
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看到 回顯内容。表明測試成功
尾語
目前基礎功能已經完成的差不了。根據計劃,之後會完善使用體驗上的内容。