踩坑记录:brpc Unknown error 1014 协议配置不当引发的自身问题

项目背景

近期团队持续拓展新业务方向,频繁对接客户端请求流量。各类 业务场景逻辑各异,交互请求的数据结构也存在明显区别。

我们的架构设计是这样,整体架构采用统一入口服务收口全量流量,再按需分发至下游各微服务。该设计便于后续统一追加通用业务数据,例如 AB 实验参数、用户画像信息等。

架构示意如下,项目现阶段处于初期阶段,目前仅实现流量转发能力,通用数据增补功能暂未落地。(红色proxy为路由分发服务)

客户端与服务端基于 HTTP 协议完成数据交互,路由服务和下游业务服务间同样采用 HTTP 协议通信。

出现问题

项目上线初期整体运行平稳稳定,各项接口请求均可正常响应。后续随着业务持续迭代优化,平台计划逐步扩容接入更多客户端流量时,在此过程中系统突发异常,接口请求失败率直接飙升至百分之百,同时后台日志批量爆出大量报错信息。 http_rpc_protocol.cpp:1044] Fail to write into Socket{id=652835031979 fd=1160 addr=10.2.27.32:32014:50050} (0x7f1b8024efc0): Unknown error 1014 1014

路由分发服务请求量监控

路由分发服务调用下游失败率监控

如图所示,接口 QPS 维持在 7000 区间时业务运行一切正常。一旦在此基础上进一步放量施压,服务调用下游接口的失败率便会瞬间骤升至百分之百;待流量回调回落至 7000 阈值后,调用异常随即消失,服务状态恢复平稳。

定位问题

项目采用业界知名、性能表现优异的开源 BRPC 框架(版本1.15)。正因框架口碑与性能优势突出,初期排查问题时,便直接排除了框架本身存在故障的可能性。

首先,查询日志捕获到 brpc 抛出Unknown error 1014错误,该报错表征网络连接被通信对端强制断开。

随后核查下游服务监控数据,发现大量请求并未正常抵达下游服务端。

初步分析得出结论:当 QPS 攀升至临界阈值后,路由分发服务发出的大量请求,均未能成功送达下游业务服务。

定位代码,服务与下游建立通信连接时,默认采用的是 HTTP/1 协议,正是这一配置成为高并发场景下的性能瓶颈。随后将通信协议调整为 HTTP/2,重新发布验证后,高 QPS 下请求失败率飙升的问题彻底解决,服务恢复稳定运行。

brpc::ChannelOptions options; options.protocol = brpc::PROTOCOL_H2;

知识点

(如有错误,请见谅)

由此便产生疑问:为何采用 HTTP1 协议通信时,QPS 突破特定阈值就会触发此类异常问题?

HTTP/1.1 属于串行通信协议,单条连接同一时刻仅能处理单个请求,需等待上一次请求响应完成后,才能发起下一次调用。QPS 升高后连接资源快速耗尽,系统会不断新建连接,当连接数触及上限便会触发连接强制断开,诱因大概率为文件句柄不足或服务端主动断连。

而 HTTP/2 支持单连接多路复用,可在同一个 TCP 连接内并发处理多路请求,连接资源利用率大幅提升。将协议切换 为 HTTP/2 后,该异常问题得以彻底解决。

相关推荐
冰暮流星12 小时前
flask之定义URL
后端·python·flask
程序员爱钓鱼13 小时前
为什么学习 Rust?Rust 能做什么?
后端·rust
二宝哥13 小时前
创建Gradle多模块SpringBoot项目
java·spring boot·后端
掘金者阿豪13 小时前
Docker命令太多记不住?用Portainer把容器管理变成可视化操作
后端
用户693717500138414 小时前
AI Agent 里的 Loop 到底是什么?
android·前端·后端
Rain的Java大神之路14 小时前
高并发下的抢优惠券如何设计
后端
钟智强14 小时前
AWS CloudGoat 实战:一个 SSRF 如何撬动整个云账户
后端
Ai拆代码的曹操14 小时前
@Transactional 写在 private 方法上,事务根本没生效
后端
云技纵横14 小时前
@Async 默认执行器又炸了:SimpleAsyncTaskExecutor 为什么不是线程池?
后端·面试
程序员Agions14 小时前
Fypro 新手快速上手与实战指南
后端