From 3df6e7fbc3233eea43e224545b239a70c773d62e Mon Sep 17 00:00:00 2001 From: "lizongsheng.chocoie" Date: Wed, 1 Jul 2026 14:54:16 +0800 Subject: [PATCH] docs(kitex): update rpcinfo usage for non pooling reuse --- .../self_check/panic_self_check.md | 2 +- .../kitex/Best Practice/usage_attention.md | 8 +++-- .../basic-feature/acquire_rpcinfo.md | 31 ++++++++++++++++--- .../Tutorials/framework-exten/middleware.md | 2 +- .../self_check/panic_self_check.md | 4 +-- .../kitex/Best Practice/usage_attention.md | 6 ++-- .../basic-feature/acquire_rpcinfo.md | 26 ++++++++++++++-- .../Tutorials/framework-exten/middleware.md | 4 +-- 8 files changed, 65 insertions(+), 18 deletions(-) diff --git a/content/en/docs/kitex/Best Practice/self_check/panic_self_check.md b/content/en/docs/kitex/Best Practice/self_check/panic_self_check.md index 2672d2c5866..609240b36da 100644 --- a/content/en/docs/kitex/Best Practice/self_check/panic_self_check.md +++ b/content/en/docs/kitex/Best Practice/self_check/panic_self_check.md @@ -341,7 +341,7 @@ Common scenarios include: ### Asynchronous Use of RPCInfo -Panic occurs when attempting to access data such as `RPCInfo` outside of the `handler` method by passing the `context` parameter of the `handler`. +Panic occurs when attempting to access data such as `RPCInfo` outside of the `handler` method by passing the `context` parameter of the `handler`. For correct usage, see [Asynchronous usage](/docs/kitex/tutorials/basic-feature/acquire_rpcinfo/#12-asynchronous-usage). ## Known Panics Resolved by Upgrading the Framework Version diff --git a/content/en/docs/kitex/Best Practice/usage_attention.md b/content/en/docs/kitex/Best Practice/usage_attention.md index e8f359db990..782796a25fd 100644 --- a/content/en/docs/kitex/Best Practice/usage_attention.md +++ b/content/en/docs/kitex/Best Practice/usage_attention.md @@ -2,16 +2,18 @@ title: "Usage Attention" linkTitle: "Usage Attention" weight: 1 -date: 2024-02-18 +date: 2026-07-01 keywords: ["Kitex", "RPCInfo", "client", "Set", "Map"] description: "This doc describes usage attentions in Kitex RPCInfo, client creation, and mass data transfer scenarios." --- ## Do not use RPCInfo asynchronously -By default, the lifecycle of Kitex's RPCInfo is from the start of the request until the response is returned (for performance reasons). Afterward, it is put into a `sync.Pool` for reuse. In the server-side, if RPCInfo is asynchronously accessed and used within the business handler, it may read dirty data or encounter a null pointer and panic. +When RPCInfo pooling and reuse is enabled, Kitex's RPCInfo lifecycle is from the start of the request until the response is returned for performance reasons. Afterward, it is put into `sync.Pool` for reuse. On the server side, if RPCInfo is asynchronously accessed and used within the business handler, dirty data or nil pointer panic may occur. -If there is indeed a scenario where asynchronous usage is required, there are two approaches: +For safety, Kitex (>= v0.16.3) disables RPCInfo pooling and reuse by default. After a request finishes, the framework does not reset RPCInfo and put it back into the pool by default. + +If asynchronous usage is required, there are two approaches: - Use `rpcinfo.FreezeRPCInfo` provided by Kitex to make a copy of the initial RPCInfo before using it. diff --git a/content/en/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md b/content/en/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md index 3636f8f2dd7..95ff119b59c 100644 --- a/content/en/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md +++ b/content/en/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md @@ -1,14 +1,34 @@ --- title: "Acquire Kitex RPC Info " -date: 2023-11-29 +date: 2026-07-01 weight: 8 keywords: ["Acquire Kitex RPC Info "] description: "" --- +> ⚠️ Note: RPCInfo pooling and reuse will be gradually removed in the versions after [v0.16.2](https://github.com/cloudwego/kitex/releases/tag/v0.16.2), in order to reduce the mental burden on users during development. + ## Acquire RPC information -The default lifecycle of Kitex's RPCInfo is from the start of the request to the return of the request (performance considerations), and then it will be placed in sync.Pool to reuse. On the Server side, if it is asynchronously obtained and used in the business Handler, it may lead to read dirty data, nil panic. +When RPCInfo pooling and reuse is enabled, Kitex's RPCInfo lifecycle is from the start of the request to the return of the request for performance reasons. After that, it is put into `sync.Pool` for reuse. On the server side, if RPCInfo is asynchronously obtained and used in a business handler, dirty data or nil pointer panic may occur. + +For safety, Kitex disables RPCInfo pooling and reuse by default. After a request finishes, the framework does not reset RPCInfo and put it back into the pool by default. Therefore, when business code reads a captured `ctx` asynchronously after the request returns, it will not panic due to the framework reusing the object and clearing its fields. + +### RPCInfo Pooling Switch + +RPCInfo pooling is disabled by default. To explicitly enable reuse, set the following environment variable: + +```bash +KITEX_ENABLE_RPCINFO_POOL=1 +``` + +The legacy disable switch is still kept for compatibility: + +```bash +KITEX_DISABLE_RPCINFO_POOL=1 +``` + +Priority: `KITEX_ENABLE_RPCINFO_POOL` > `KITEX_DISABLE_RPCINFO_POOL` **Note:** Some information needs to rely on the transport protocol (TTHeader or HTTP2) and corresponding MetaHandler. Please refer to [here](/docs/kitex/tutorials/basic-feature/protocol/transport_protocol/#thrift). @@ -26,7 +46,9 @@ The default lifecycle of Kitex's RPCInfo is from the start of the request to the ### 1.2 Asynchronous usage -If you need to get RPCInfo in the new goroutine, there are two ways to use it. Choose one and get the specific information as above. +> If the framework version is earlier than v0.16.2 and the environment variable `KITEX_DISABLE_RPCINFO_POOL=true` is not explicitly set + +If you need to get RPCInfo in a new goroutine, there are two ways to use it. Choose one and get the specific information as above. - **Method 1:** Use the rpcinfo.FreezeRPCInfo provided by Kitex to copy the initial RPCInfo and then use it. However, there is additional consumption due to deep copying of rpcinfo. @@ -49,8 +71,7 @@ go func(ctx context.Context) { ``` -- **Method 2 [Kitex v0.8.0+]:** Disable RPCInfo pool - Set environment variables _KITEX_DISABLE_RPCINFO_POOL=true_ or configure _rpcinfo.EnablePool(false)_ in the code. +- **Method 2 [Kitex v0.8.0+]:** Disable RPCInfo recycling. You can either set the environment variable `KITEX_DISABLE_RPCINFO_POOL=true`, or configure `rpcinfo.EnablePool(false)` in code. ## Meta Info Transparent Transmission diff --git a/content/en/docs/kitex/Tutorials/framework-exten/middleware.md b/content/en/docs/kitex/Tutorials/framework-exten/middleware.md index 159e83cf108..ee31b5d115a 100644 --- a/content/en/docs/kitex/Tutorials/framework-exten/middleware.md +++ b/content/en/docs/kitex/Tutorials/framework-exten/middleware.md @@ -124,7 +124,7 @@ The provided example is for illustrative purposes, and it is indeed important to ### Precautions -1. If RPCInfo is used in custom middleware, be aware that RPCInfo will be recycled after the rpc ends, so if you use goroutine operation RPCInfo in middleware, there will be issues . Please avoid such operations . +1. [Kitex <= v0.16.2] If RPCInfo is used in custom middleware, be aware that RPCInfo will be recycled after the rpc ends. If you operate RPCInfo in a goroutine in middleware, issues may occur. Please avoid such operations. For details, see [Asynchronous usage](/docs/kitex/tutorials/basic-feature/acquire_rpcinfo/#12-asynchronous-usage). 2. Middleware is a chained call, if you use `result. SetSuccess()` or some other way to modify the response in any middleware, the upstream middlewares will receive the modified response. ### gRPC Middleware diff --git a/content/zh/docs/kitex/Best Practice/self_check/panic_self_check.md b/content/zh/docs/kitex/Best Practice/self_check/panic_self_check.md index ff8fd68febd..d4c21d2f945 100644 --- a/content/zh/docs/kitex/Best Practice/self_check/panic_self_check.md +++ b/content/zh/docs/kitex/Best Practice/self_check/panic_self_check.md @@ -2,7 +2,7 @@ title: "Panic 自查手册" linkTitle: "Panic 自查手册" weight: 1 -date: 2024-02-18 +date: 2026-07-01 description: "发生 Panic 时如何快速排查" --- @@ -343,7 +343,7 @@ Map 并发操作属于不可挽回的错误,因此系统会直接 crash,无 ### 异步使用 RPCInfo -将 `handler` 方法的 `context` 参数传递到 `handler` 外使用并尝试获取诸如 `RPCInfo` 这样的数据导致 panic。 +将 `handler` 方法的 `context` 参数传递到 `handler` 外使用并尝试获取诸如 `RPCInfo` 这样的数据导致 panic。正确使用方式见 [异步使用方式](/zh/docs/kitex/tutorials/basic-feature/acquire_rpcinfo/#12-异步使用方式)。 ## 已知升级框架版本可解决的 Panic diff --git a/content/zh/docs/kitex/Best Practice/usage_attention.md b/content/zh/docs/kitex/Best Practice/usage_attention.md index 1b7314dc2b1..52e997191bd 100644 --- a/content/zh/docs/kitex/Best Practice/usage_attention.md +++ b/content/zh/docs/kitex/Best Practice/usage_attention.md @@ -2,14 +2,16 @@ title: "使用注意事项" linkTitle: "使用注意事项" weight: 1 -date: 2024-02-18 +date: 2026-07-01 keywords: ["Kitex", "RPCInfo", "client", "Set", "Map"] description: "介绍 Kitex RPCInfo、client 创建、大量数据传输场景下的注意事项。" --- ## 勿异步使用 RPCInfo -Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性能考虑),随后会被放到 `sync.Pool` 中复用,在 Server 端,如果在业务 Handler 中异步获取使用,可能会读到脏数据 / 空指针而 panic。 +当开启 RPCInfo 池化复用功能时,Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性能考虑),随后会被放到 `sync.Pool` 中复用,在 Server 端,如果在业务 Handler 中异步获取使用,可能会读到脏数据 / 空指针而 panic。 + +出于安全性考虑,Kitex (>= v0.16.3) 默认关闭 RPCInfo 池化复用。请求结束后,框架不会默认将 RPCInfo 重置并放回池中。 如果的确存在异步使用的场景,有两种方式: diff --git a/content/zh/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md b/content/zh/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md index 079b688bea3..e44e82b3e61 100644 --- a/content/zh/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md +++ b/content/zh/docs/kitex/Tutorials/basic-feature/acquire_rpcinfo.md @@ -1,14 +1,34 @@ --- title: "框架 RPC 信息的获取" -date: 2023-11-29 +date: 2026-07-01 weight: 8 keywords: ["框架 RPC 信息的获取"] description: "" --- +> ⚠️ 注意:RPCInfo 将在 [v0.16.2](https://github.com/cloudwego/kitex/releases/tag/v0.16.2) 的后续几个版本逐步删除池化复用,以便于降低用户开发时的心智负担。 + ## 从 RPCInfo 获取 RPC 信息 -Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性能考虑),随后会被放到 sync.Pool 中复用。在 Server 端,如果在业务 Handler 中异步获取使用,可能会读到脏数据 / 空指针而 panic。 +当开启 RPCInfo 池化复用功能时,Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性能考虑),随后会被放到 sync.Pool 中复用。在 Server 端,如果在业务 Handler 中异步获取使用,可能会读到脏数据 / 空指针而 panic。 + +出于安全性考虑,Kitex 默认关闭 RPCInfo 池化复用。请求结束后,框架不会默认将 RPCInfo 重置并放回池中,因此业务在请求结束后异步读取已捕获的 `ctx` 时,不会因为框架复用该对象而读到空字段并 panic。 + +### RPCInfo 池化开关 + +RPCInfo 池化复用默认关闭。需要显式开启复用时,可以设置环境变量: + +```bash +KITEX_ENABLE_RPCINFO_POOL=1 +``` + +兼容旧版本的关闭开关仍然保留: + +```bash +KITEX_DISABLE_RPCINFO_POOL=1 +``` + +优先级:`KITEX_ENABLE_RPCINFO_POOL` > `KITEX_DISABLE_RPCINFO_POOL` **注意:** 部分信息需要依赖传输协议(TTHeader 或 HTTP2)和对应的 Metahandler,如果是 Thrift 配置方式见 [这里](/zh/docs/kitex/tutorials/basic-feature/protocol/transport_protocol/#thrift)。 @@ -28,6 +48,8 @@ Kitex 的 RPCInfo 的生命周期默认是从请求开始到请求返回(性 ### 1.2 异步使用方式 +> 如果框架版本小于 v0.16.2,并没有显式设置环境变量 `KITEX_DISABLE_RPCINFO_POOL=true` + 如果需要在新的 Goroutine 里获取 RPCInfo,有两种使用方式,选择其中一种,获取具体信息与上面一样。 - **方式一:** 用 Kitex 提供的 rpcinfo.FreezeRPCInfo 复制初始的 RPCInfo 再使用 diff --git a/content/zh/docs/kitex/Tutorials/framework-exten/middleware.md b/content/zh/docs/kitex/Tutorials/framework-exten/middleware.md index 02465742a5e..f189ef8d380 100644 --- a/content/zh/docs/kitex/Tutorials/framework-exten/middleware.md +++ b/content/zh/docs/kitex/Tutorials/framework-exten/middleware.md @@ -1,6 +1,6 @@ --- title: "Middleware 扩展" -date: 2021-08-26 +date: 2026-07-01 weight: 1 description: > --- @@ -125,7 +125,7 @@ func ExampleMiddleware(next endpoint.Endpoint) endpoint.Endpoint { ### 注意事项 -1. 如果自定义 middleware 中用到了 RPCInfo,注意 RPCInfo 在 rpc 结束之后会被回收。如果在 middleware 中开启 goroutine 操作 RPCInfo 有可能会出现问题,请避免这类操作。 +1. [Kitex <= v0.16.2] 如果自定义 middleware 中用到了 RPCInfo,注意 RPCInfo 在 rpc 结束之后会被回收。如果在 middleware 中开启 goroutine 操作 RPCInfo 有可能会出现问题,请避免这类操作,详情见 [异步使用方式](/zh/docs/kitex/tutorials/basic-feature/acquire_rpcinfo/#12-异步使用方式)。 2. Middleware 为链式调用,若在任一 middleware 中使用 `result.SetSuccess()` 或其他方式修改了 response,上游 middleware 会接收到修改后的 response。 ### gRPC 中间件