携程亿级网关架构设计
《携程亿级网关架构设计》共 0.4 万字,通篇围绕 场景、安全、上下文、架构 展开,归在「后端与系统架构」这一层。
适合给 AI 系统搭底座、要管得住的人
目录骨架(4 节)
- 一、概述
- 二、高性能网关核心设计
- 四、网关治理
- 五、总结
分享内容
- 高性能网关之异步流程设计
- 高性能网关之流式转发 & 单线程
- 网关业务形态
- 网关治理:多协议兼容、路由模块、模块编排
一、概述
类似于许多企业的做法,携程 API 网关是伴随着微服务架构一同引入的基础设施,其最初版本于 2014 年发布。随着服务化在公司内的迅速推进,网关逐步成为应用程序暴露在外网的标准解决方案。后续的 “ALL IN 无线”、国际化、异地多活等项目,网关都随着公司公共业务与基础架构的共同演进而不断发展。截至 2021 年 7 月,整体接入服务数量超过 3000 个,日均处理流量达到 200 亿。
在技术方案方面,公司微服务的早期发展深受 NetflixOSS 的影响,网关部分最早也是参考了 Zuul 1.0 进行的二次开发,其核心可以总结为以下四点:
- server 端:Tomcat NIO + AsyncServlet
- 业务流程:独立线程池,分阶段的责任链模式
- client 端:Apache HttpClient,同步调用
- 核心组件:Archaius(动态配置客户端),Hystrix(熔断限流),Groovy(热更新支持)

众所周知,同步调用会阻塞线程,系统的吞吐能力受 IO 影响较大。
作为行业的领先者,Zuul 在设计时已经考虑到了这个问题:通过引入 Hystrix,实现资源隔离和限流,将故障(慢 IO)限制在一定范围内;结合熔断策略,可以提前释放部分线程资源;最终达到局部异常不会影响整体的目标。
然而,随着公司业务的不断发展,上述策略的效果逐渐减弱,主要原因有两方面:
- 业务出海:网关作为海外接入层,部分流量需要转回国内,慢 IO 成为常态
- 服务规模增长:局部异常成为常态,加上微服务异常扩散的特性,线程池可能长期处于亚健康状态

全异步改造是携程 API 网关近年来的一项核心工作,我们探讨在网关方面的工作与实践经验。
重点包括:性能优化、业务形态、技术架构、治理经验等。
二、高性能网关核心设计
2.1. 异步流程设计
全异步 = server 端异步 + 业务流程异步 + client 端异步
对于 server 与 client 端,我们采用了 Netty 框架,其 NIO/Epoll + Eventloop 的本质就是事件驱动的设计。
我们改造的核心部分是将业务流程进行异步化,常见的异步场景有:
- 业务 IO 事件:例如请求校验、身份验证,涉及远程调用
- 自身 IO 事件:例如读取到了报文的前 xx 字节
- 请求转发:包括 TCP 连接,HTTP 请求
从经验上看,异步编程在设计和读写方面相比同步会稍微困难一些,主要包括:
- 流程设计 & 状态转换
- 异常处理,包括常规异常与超时
- 上下文传递,包括业务上下文与 trace log
- 线程调度
- 流量控制
特别是在 Netty 上下文内,如果对 ByteBuf 的生命周期设计不完善,很容易导致内存泄漏。
围绕这些问题,我们设计了对应外围框架,最大努力对业务代码抹平同步 / 异步差异,方便开发;同时默认兜底与容错,保证程序整体安全。
在工具方面,我们使用了 RxJava,其主要流程如下图所示。

- Maybe
- RxJava 的内置容器类,表示正常结束、有且仅有一个对象返回、异常三种状态
- 响应式,便于整体状态机设计,自带异常处理、超时、线程调度等封装
- Maybe.empty()/Maybe.just(T),适用同步场景
- 工具类 RxJavaPlugins,方便切面逻辑封装
- Filter
- 代表一块独立的业务逻辑,同步 & 异步业务统一接口,返回 Maybe
- 异步场景(如远程调用)统一封装,如涉及线程切换,通过 maybe.obesrveOn(eventloop) 切回
- 异步 filter 默认增加超时,并按弱依赖处理,忽略错误
- 整体流程
- 沿用责任链的设计,分为 inbound、outbound、error、log 四阶段
- 各阶段由一或多个 filter 组成
- filter 顺序执行,遇到异常则中断,inbound 期间任意 filter 返回 response 也触发中断
2.2. 流式转发 & 单线程
以 HTTP 为例,报文可划分为 initial line/header/body 三个组成部分。
