news 2026/10/20 2:19:43

网关架构:喜马拉雅百亿次日调用Netty网关架构演进路线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
网关架构:喜马拉雅百亿次日调用Netty网关架构演进路线

喜马拉雅百亿次日调用Netty网关架构演进路线

喜马拉雅用户超过 6 亿,Web 服务超过 500 个,网关每天处理超过 200 亿次调用,单机 QPS 峰值可达 4 万以上。网关从 Tomcat NIO + Async Servlet 演进到 Netty + 全异步,核心是解决代理场景中的阻塞、对象池、连接池和超时管理问题。

一、第一版:Tomcat NIO + Async Servlet

第一版网关使用 Tomcat NIO 和 Async Servlet,并实现了一个单独的 Push 层与后端服务通信。功能上已经支持黑白名单、流量控制、身份验证和 API 发布。

但 Tomcat 作为接入端很快成为瓶颈:

  • 缓存过多,对象池在内存有限、流量增大时容易触发 GC;
  • 堆内存与 Netty 后端堆外内存之间存在多次 Copy;
  • Tomcat 的 NIO 读 Body 是阻塞的;
  • 默认缓存大量requestProcessor,每个都关联 Request;
  • Servlet 3.0 异步实现可能导致内存泄漏。

当单机 QPS 达到 5000 时,Full GC 频繁发生。

二、第二版:Netty + 全异步

Netty 版本构建了全异步、无锁、分层的架构:

客户端

接入层
HTTP 编解码

业务逻辑层
责任链 Filter

服务调用层
异步 Push + 连接池

后端服务

接入层

Netty IO 线程负责 HTTP 编解码和协议异常监控。相比 Tomcat 将请求行和请求头一起限制 8K,Netty 可以分别限制大小。请求超过阈值时,优化后只取正常大小部分并标记解析失败,业务层可以进一步判断问题来源。

业务逻辑层

业务逻辑层采用责任链模式,不进行 IO 操作。支持的流量治理能力包括:

  • 用户认证和登录验证;
  • 黑白名单;
  • 令牌桶限流;
  • 智能熔断;
  • 灰度发布和慢启动预热;
  • 统一降级;
  • 流量调度;
  • 流量 Copy;
  • 请求日志采样。

规则元数据在网关启动时全部初始化,运行时规则变化通过独立线程刷新,避免 IO 操作影响业务线程。

服务调用层

服务调用层必须异步。每个请求创建上下文,发送请求后把 Context 绑定到连接上,收到响应后再取出 Context 写回客户端。

HTTP 连接是独占的,释放时必须等响应完成。需要关闭连接的场景包括Connection: close、空闲超时、读超时、写超时、FIN、Reset。

后端 Tomcat 默认连接重用 100 次,达到限制后会返回Connection: close,因此长连接场景需要主动移除 close 头。

三、全链路超时机制

超时不能只在响应阶段计算,而要覆盖整个链路:

协议解析超时

等待队列超时

建连超时

等待连接超时

写前检查超时

写超时

响应超时

写超时的计时点很重要。如果从writeAndFlush开始计时,会包含 HTTP 编码和队列发送时间,对后端不公平。因此应在 flush 成功回调后启动超时任务。大 POST 请求可能分多次 flush,若回调迟迟不完成,写超时可以及时关闭连接。

四、监控报警

网关监控分为协议层和应用层:

  • 协议层:攻击性请求、Line/Head/Body 过大、只发头不发 Body;
  • 应用层:慢请求、超时、TP99/TP999、OPS、带宽、响应码、连接状态、失败请求、流量抖动。

监控数据定时上传到管理系统,汇总后存储到 InfluxDB,实现秒级报警。

五、性能优化

对象池

复用线程池任务、StringBuffer 等频繁创建的对象,降低内存分配和 GC 压力。

上下文切换

网关业务逻辑处理采用 Netty IO 编解码线程异步方式,一方面防止业务代码阻塞,另一方面在日志激增等突发情况下允许使用 Netty IO 线程作为替代,减少上下文切换。

GC 优化

采用对象池和堆外内存,尽量让对象在年轻代回收。但监控发现老年代仍缓慢增长。原因在于每个后端连接创建的 socket 中,AbstractPlainSocketImpl重写了finalize():

/** * Cleans up if the user forgets to close it. */protectedvoidfinalize()throwsIOException{close();}

finalize由优先级不高的 Finalizer 线程处理,对象需要等待 finalize 完成并在下次 GC 时才能回收,因此进入老年代。这说明主动、确定性地关闭连接比依赖 finalize 更重要。

日志

Log4j ConsoleAppender 默认immediateFlush=true,每次同步写盘。AsyncAppender 的 buffer 默认 128 且会阻塞,当 Dispatcher 刷盘变慢时可能阻塞 Netty IO 线程。因此高并发场景必须精简日志。

六、未来规划

HTTP/2 在连接层实现多路复用,一个连接可以发送多个请求,解决 HTTP/1 连接无法复用导致的重复建连和慢启动开销。喜马拉雅正基于 Netty 升级 HTTP/2,同时继续完善监控报警和统一降级能力。

七、总结

喜马拉雅网关的核心经验是:代理网关最不能接受的是阻塞。第一版证明了 Tomcat 异步 Servlet 在功能上可行但性能上受限,第二版通过 Netty 全异步、无锁分层、连接池、超时管理和 GC 优化解决了高吞吐问题。监控和日志也不是辅助功能,而是高并发网关能否稳定运行的一部分。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 2:19:14

洛谷 P8611:蚂蚁感冒 ← 模拟题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 2:18:18

上海数据集团职位分析:子公司财务总监

岗位定位:国资体系子公司高管级财务负责人(CFO),属于经营决策层核心岗位,区别于财务主管、财务经理的执行管控岗,核心定位为全盘财务统筹管控+财务制度体系搭建+经营决策支撑+资金投融资管控+国资合规风控+业财深度融合的高管岗位。对上承接上海数据集团总部财务战略与管…

作者头像 李华
网站建设 2026/10/20 2:17:48

【智能路灯节电稳压远程控制:从“无人值守”走向“城市能源神】

当无人值守成为常态,沃思智能并未停下进化的脚步。如果说4.0版本让路灯学会了自主决策,那么如今的5.0版本,则让路灯开始与整座城市“对话”——节电稳压远程控制不再只是孤立的路灯管理系统,而是融入城市能源物联网的智慧神经末梢…

作者头像 李华
网站建设 2026/10/20 2:17:44

Linux 系统编程(一):进程控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 2:17:42

全本地 RAG 栈实战:数据不出门,私有化部署一条龙

个人主页&#xff1a;> for_ever_love__ <&#xff08;欢迎各位大佬莅临&#x1f60a;&#xff09; 其他栏目: > 大模型开发从0到1 < 其他栏目: > iOS项目总结大全 < 其他栏目: > 我想学python了 < 其他栏目: > iOS UI < 文章目录全本地 RAG 栈实…

作者头像 李华