框架 RPC 信息的获取
从 RPCInfo 获取 RPC 信息
Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性能考虑),随后会被放到 sync.Pool 中复用。在 Server 端,如果在业务 Handler 中异步获取使用,可能会读到脏数据 / 空指针而 panic。
1.1 同步使用方式
同步的使用方式是指用户没有在新起的 Goroutine 里获取 RPCInfo。
获取的信息 | Kitex 获取方式 |
---|---|
获取调用方的 Service | caller, ok := kitexutil.GetCaller(ctx) |
获取 RPC 方法名 | method, ok := kitexutil.GetMethod(ctx) |
获取调用方的请求地址 | cluster, ok := kitexutil.GetCallerAddr(ctx) |
获取 IDL 里定义的 ServiceName | svcName, ok := kitexutil.GetIDLServiceName(ctx) |
获取调用方的 handler 接口名 | callerMethod, ok := kitexutil.GetCallerHandlerMethod(ctx) 只有调用方也是 Kitex Server 才默认有这个信息,或者调用方主动将 K_METHOD 写入 context.Context 中,Kitex 会获取该信息传输给服务端。 |
获取传输协议 | tp, ok := kitexutil.GetTransportProtocol(ctx) |
调用端获取请求的服务端的地址 | ctx = metainfo.WithBackwardValues(ctx) // 先设置 ctx,再执行 RPC 调用 …err, resp := cli.YourMethod(ctx, req)rip, ok := metainfo.GetBackwardValue(ctx, consts.RemoteAddr) 注意:不适用于 oneway 方法 |
1.2 异步使用方式
如果需要在新的 Goroutine 里获取 RPCInfo,有两种使用方式,选择其中一种,获取具体信息与上面一样。
- 方式一: 用 Kitex 提供的 rpcinfo.FreezeRPCInfo 复制初始的 RPCInfo 再使用
import (
"github.com/cloudwego/kitex/pkg/rpcinfo"
"github.com/cloudwego/kitex/pkg/utils/kitexutil"
)
// this creates a read-only copy of `ri` and attaches it to the new context
ctx2 := rpcinfo.FreezeRPCInfo(ctx)
go func(ctx context.Context) {
// ...
ri := rpcinfo.GetRPCInfo(ctx) // OK
// eg: get client psm
// caller, ok := kitexutil.GetCaller(ctx)
//...
}(ctx2)
- 方式二 [Kitex v0.8.0+]: 关闭 RPCInfo 回收,以下二选一即可
环境变量设置
KITEX_DISABLE_RPCINFO_POOL=true
或者代码里配置rpcinfo.EnablePool(false)
。
元信息透传
详见 元信息透传。
最后修改
January 18, 2024
: Upload volo blog (#936) (1fc8abb)