Kitex Metainfo

2022-04-27 09:53 更新

元信息

作為一個(gè) RPC 框架,Kitex 服務(wù)之間的通信都是基于 IDL(thrift、protobuf 等)描述的協(xié)議進(jìn)行的。IDL 定義的服務(wù)接口決定了客戶(hù)端和服務(wù)端之間可以傳輸?shù)臄?shù)據(jù)結(jié)構(gòu)。

然而在實(shí)際生產(chǎn)環(huán)境,我們偶爾會(huì)有特殊的信息需要傳遞給對(duì)端服務(wù),而又不希望將這些可能是臨時(shí)或者格式不確定的內(nèi)容顯式定義在 IDL 里面,這就需要框架能夠支持一定的元信息傳遞能力。

如果底層傳輸協(xié)議支持(例如 TTheader、HTTP),那么 Kitex 可以進(jìn)行元信息的透?jìng)鳌?

為了和底層的協(xié)議解耦,同時(shí)也為了支持與不同框架之間的互通,Kitex 并沒(méi)有直接提供讀寫(xiě)底層傳輸協(xié)議的元信息的 API,而是通過(guò)一個(gè)獨(dú)立維護(hù)的基礎(chǔ)庫(kù) metainfo 來(lái)支持元信息的傳遞。

正向元信息傳遞

包 metainfo 提供了兩種類(lèi)型的正向元信息傳遞 API:臨時(shí)的(transient)和持續(xù)的(persistent)。前者適用于通常的元信息傳遞的需求;后者是在對(duì)元信息有持續(xù)傳遞需求的場(chǎng)合下使用,例如日志 ID、染色等場(chǎng)合,當(dāng)然,持續(xù)傳遞的前提是下游以及更下游的服務(wù)都是支持這一套數(shù)據(jù)透?jìng)鞯募s定,例如都是 Kitex 服務(wù)。

客戶(hù)端的例子:

import "github.com/bytedance/gopkg/cloud/metainfo"

func main() {
    ...
    ctx := context.Background()
    cli := myservice.MustNewClient(...)
    req := myservice.NewSomeRequest()

    ctx = metainfo.WithValue(ctx, "temp", "temp-value")       // 附加元信息到 context 里
    ctx = metainfo.WithPersistentValue(ctx, "logid", "12345") // 附加能持續(xù)透?jìng)鞯脑畔?    resp, err := cli.SomeMethod(ctx, req)                     // 將得到的 context 作為客戶(hù)端的調(diào)用參數(shù)
    ...
}

服務(wù)端的例子:

import (
    "context"

    "github.com/bytedance/gopkg/cloud/metainfo"
)

var cli2 = myservice2.MustNewClient(...) // 更下游的服務(wù)的客戶(hù)端

func (MyServiceImpl) SomeMethod(ctx context.Context, req *SomeRequest) (res *SomeResponse, err error) {
    temp, ok1 := metainfo.GetValue(ctx, "temp")
    logid, ok2 := metainfo.GetPersistentValue(ctx, "logid")

    if !(ok1 && ok2) {
        panic("It looks like the protocol does not support transmitting meta information")
    }
    println(temp)  // "temp-value"
    println(logid) // "12345"

    // 如果需要調(diào)用其他服務(wù)的話
    req2 := myservice2.NewRequset()
    res2, err2 := cli2.SomeMethod2(ctx, req2) // 在調(diào)用其他服務(wù)時(shí)繼續(xù)傳遞收到的 context,可以讓持續(xù)的元信息繼續(xù)傳遞下去
    ...
}

反向元信息傳遞 

一些傳輸協(xié)議還支持反向的元數(shù)據(jù)傳遞,因此 Kitex 也利用 metainfo 做了支持。

客戶(hù)端的例子:

import "github.com/bytedance/gopkg/cloud/metainfo"

func main() {
    ...
    ctx := context.Background()
    cli := myservice.MustNewClient(...)
    req := myservice.NewSomeRequest()

    ctx = metainfo.WithBackwardValues(ctx) // 標(biāo)記要接收反向傳遞的數(shù)據(jù)的 context
    resp, err := cli.SomeMethod(ctx, req)  // 將得到的 context 作為客戶(hù)端的調(diào)用參數(shù)

    if err == nil {
        val, ok := metainfo.RecvBackwardValue(ctx, "something-from-server") // 獲取服務(wù)端傳回的元數(shù)據(jù)
        println(val, ok)
    }
    ...
}

服務(wù)端的例子:

import (
    "context"

    "github.com/bytedance/gopkg/cloud/metainfo"
)

func (MyServiceImpl) SomeMethod(ctx context.Context, req *SomeRequest) (res *SomeResponse, err error) {
    ok := metainfo.SendBackwardValue(ctx, "something-from-server")

    if !ok) {
        panic("It looks like the protocol does not support transmitting meta information backward")
    }
    ...
}


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)