后端架构

线程池一切换 traceId 就丢,我在 gRPC 的拦截器和异步调用链上做了三层上下文固定

gRPC 链路追踪中 traceId 丢失的核心原因是线程切换导致基于 ThreadLocal 的上下文断链。解决方案分三层:拦截器提取元数据写入 gRPC Context;线程池切换时用 Context.wrap() 显式传递;异步回调通过 attach/detach 重新绑定。同时将 traceId 打入 MDC 并处理客户端拦截器,确保全链路日志可追踪。

后端架构

那次 gRPC 连接每隔两分钟就断,最后发现是 Keepalive 的 permit-keepalive-time 配反了

gRPC 服务每隔两分钟规律性断连,根源是客户端 keepalive 发送频率(30秒)远高于服务端允许的最小间隔(120秒),导致服务端主动踢掉连接。核心约束是客户端 `keepalive_time_ms` 必须大于等于服务端 `permit-keepalive-time`,否则必然触发 `ENHANCE_YOUR_CALM` 错误。调参需先摸清网络中间件 idle timeout,确保客户端心跳周期小于该值,再让服务端容忍度匹配客户端频率,并显式开启空闲连接心跳。

后端架构

四种 gRPC 流式服务端,我们踩坑后终于知道什么时候该用哪种了

gRPC 四种服务端类型各有适用场景,选错代价高昂。Unary 适合一问一答,天然支持背压控制;Server Streaming 用于数据推送,但必须配合分页和超时机制防止内存溢出;Client Streaming 适合批量上传,需在收到 EOF 后统一事务处理;Bidirectional Streaming 用于实时双向通信,要严格管理协程生命周期。决策关键在于匹配业务的数据流向和速率特征,避免过度设计。