后端架构

oneof 和 wrapper 在 Protobuf 里都能表达“可选”,但序列化后的字节数差了一倍,代码里判空的方式也完全不同

wrapper 类型因多一层 length-delimited 嵌套,序列化体积比 oneof 大,尤其对 varint 类型差距可达一倍。代码判空上,wrapper 用指针判 nil 更直觉,oneof 需类型断言,心智负担重。oneof 适合多字段互斥场景,能自动清旧值;仅需区分 null 和零值时,推荐用原生 optional 关键字,兼顾小体积和简洁判空。

后端架构

把压测标识塞进 gRPC metadata,一路透传到 DB 层,流量自动落到影子库,这套链路我搭了一遍

压测流量污染线上数据是常见痛点。利用 gRPC metadata 作为压测标识载体,可从网关注入标记并全链路透传至 DAO 层,实现自动切换影子库,无需修改业务代码。方案核心包括网关注入、客户端与服务端拦截器自动传递、ORM 层动态路由,并通过链路追踪兜底防止标记中断,还支持生产流量回放压测。

后端架构

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

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

后端架构

Protobuf 字段编号改到一半,下游解析突然不报错了,那才是兼容性事故的开始

Protobuf 字段编号修改后,解析器因未知字段保留机制不报错,导致核心业务字段静默取默认值,引发数据丢失。问题根源在于兼容性设计被绕过,而非语法错误。文章提出三项硬约束:禁止修改字段编号并用 reserved 占位、跨团队 proto 走共享仓库版本化、关键字段加校验拦截默认值,并分享了抓包分析和多版本兼容测试的排查方法。

后端架构

调了半天限流参数,结果发现把拉取批次和本地队列的配置搞反了——消息全堵在消费端

消费延迟飙升,问题不在拉取批次太小,而在本地队列深度配置反了。`max.poll.records`控制拉取效率,`QueueDepth`才是限流关键。正确做法是拉取要快、队列要浅,让背压发生在业务处理入口,而非与broker的交互上。调整后积压迅速消化,CPU利用率回升。

后端架构

系统资源吃紧的时候,熔断和限流到底谁先动手?我们翻了 Resilience4j 的源码排了个序,不然两套逻辑真会打起来

凌晨三点订单服务崩溃,线程池满、CPU飙升,熔断器和限流器同时触发却相互冲突。问题根源在于Resilience4j中,注解模式下Bulkhead切面优先级高于CircuitBreaker,会先限流;但函数式组合时,decorate顺序决定执行先后。我们误将熔断器包在外层,导致线程池满引发的超时被熔断器计为失败,错误率虚高触发误熔断。解决方案是调整包裹顺序,让Bulkhead先执行,并统一使用注解模式,优化参数配置,最终消除误触发。

后端架构

限流组件自己成了瓶颈,把正则匹配换成前缀树后,QPS 直接翻了一倍

限流组件在高并发下因正则匹配成为性能瓶颈,CPU占比高达67%。通过将匹配逻辑从正则改为前缀树,QPS从6.2万飙升至13.5万,CPU使用率大幅下降,延迟减半,内存占用也显著降低。前缀树适合路径前缀匹配场景,规则数量多时优势明显,改造简单且无需停服。

后端架构

降级开关拆到方法级以后,风控校验被悄悄跳过了,等发现时订单都跑出去好几千条

一场因方法级降级开关精细化拆分引发的事故:风控校验方法降级时默认返回null,导致调用方直接放行,三千多笔订单跳过风控。根因是不同业务方法的降级默认值语义不同,而AOP切面统一返回null。修复方案包括回滚开关、强制声明降级行为、禁止安全相关方法自动降级,并增设风控请求量监控。核心教训是降级默认值应是业务决策,而非技术偷懒。

后端架构

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

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

后端架构

把限流阈值从代码里拽出来之后,我们设计了一套 DSL,运营活动期间自己改配置就行

运营侧限流阈值变更平均耗时4.2小时,核心矛盾是决策权与执行权分离。方案设计了一套三层DSL(活动-场景-规则),将业务语义从技术参数剥离,运营通过管理后台直接调整阈值,秒级生效。规则引擎采用Redis热加载与原子替换,权限模型按活动和操作类型细粒度隔离,将生效时间降至27秒,且零误操作。