API 网关 TLS 优化中,价值最高的措施通常是避免不必要的握手:让客户端到网关、网关到上游的连接都能复用,在适合的场景启用并验证会话恢复,并选择不会反复跨越长距离网络路径的 TLS 终止拓扑。在调整加密算法前,应分别测量新建连接和复用连接。
安全约束必须优先。应保持所需的协议版本、证书验证和密钥保护级别,在这一边界内优化,而不是为跑分削弱安全性。
核心要点
- 每次测量都要区分连接建立与稳定状态下的请求处理。
- 复用一个已认证连接通常比微调单项密码运算节省更多工作。
- 在常见的完整握手场景中,TLS 1.3 比 TLS 1.2 减少了握手往返次数,但网络路径和连接行为仍主导许多工作负载。
- 必须在真实网关集群中测试会话恢复,包括轮换和故障转移。
- TLS 1.3 的 0-RTT 数据存在重放风险,不要轻易为会改变状态的 API 启用它。
- 如果网关通过 HTTPS 或 mTLS 访问上游,两个 TLS 区段都要优化。
建立 TLS 成本模型
一次经过网关的 HTTPS 请求可能包含两条相互独立的安全连接:
1flowchart LR
2 C[客户端] <-->|TLS 连接 A| G[API 网关]
3 G <-->|TLS 连接 B| U[上游 API]每条新连接都可能需要建立 TCP 连接、执行 TLS 握手、传输并验证证书链、完成密钥协商,以及设置对称密钥。DNS、路由、代理和丢包还会在这些步骤周围增加耗时。会话建立后,应用数据记录使用成本低得多的对称加密,但载荷大小和 CPU 消耗仍然重要。
更改配置前,先回答四个问题:
- 有多少比例的请求使用新的客户端连接?
- 网关能否复用上游连接?
- 延迟中有多少来自网络往返,有多少来自网关 CPU?
- 会话恢复在不同实例和部署之间是否真的成功?
如果几乎每个请求都会创建两条新的安全连接,调整密码套件很难解决这种架构浪费。
测量新建、复用和恢复连接路径
应使用与生产环境具有相同证书链、网关拓扑、协议协商和上游 TLS 行为的预发布端点。测试要覆盖真实网络距离;本地主机环境会隐藏握手往返时间。
使用 curl 检查一条连接
curl 可以显示一些有用的计时字段:
1curl --silent --output /dev/null \
2 --write-out 'connect=%{time_connect} tls=%{time_appconnect} start=%{time_starttransfer} total=%{time_total}\n' \
3 https://api.example.com/health
time_appconnect 表示从开始到 SSL/SSH 握手完成的耗时。应将其与 time_connect、首字节时间和总耗时一起比较。单次请求只是诊断样本,并非性能结论。
检查协商出的会话
1openssl s_client \
2 -connect api.example.com:443 \
3 -servername api.example.com \
4 -tls1_3 </dev/null检查协商协议、证书链、验证结果和应用协议。不要用 -verify_quiet 或其他隐藏输出的选项代替真正的验证。
明确区分连接行为进行基准测试
分别运行以下场景:
- 每个请求新建一条连接;
- 在一条持久连接上连续发送多个请求;
- 使用符合实际的并发持久连接;
- 已建立会话后的会话恢复;
- 实例轮换、横向扩容和故障;
- 客户端与上游两个区段的 TLS。
记录每秒握手数、每连接请求数、会话恢复成功率、CPU、延迟百分位、错误率和传输字节数。负载生成器的默认连接池可能意外地把握手测试变成 Keep-Alive 测试,或反过来。
优化一:复用连接
持久化 HTTP/1.1 连接、HTTP/2 多路复用和 HTTP/3 都能在一条已认证连接上承载多个请求,从而摊薄 TCP 与 TLS 建立成本。最合适的协议取决于客户端支持、请求模式、队头阻塞行为和网络条件;应通过基准测试判断,而不是预设答案。
检查每一个网络跳点:
- 客户端连接复用和空闲超时;
- 负载均衡器或 CDN 到网关的连接复用;
- 网关到上游的 Keep-Alive 连接池;
- 上游空闲超时和每连接最大请求数;
- 中间 NAT 或防火墙的空闲超时。
各层超时必须协调。如果中间设备比客户端更早静默关闭连接,下一个请求可能要承担重置、重试和重新握手的成本。但空闲超时过长也会长期占用套接字和内存。应根据复用间隔和容量选择超时,并观察实际结果。
连接复用也会改变负载分布。少量长期存在的 HTTP/2 连接可能把工作集中到更少的网关实例。要确认负载均衡器和网关集群在真实连接模型下仍能保持均衡。
优化二:在不削弱安全策略的前提下使用当前协议
根据 Apache APISIX 的安全威胁模型,APISIX 3.18 默认支持 TLS 1.2 和 TLS 1.3。TLS 1.0 和 1.1 被认为较弱,默认不启用。协议选择应同时满足客户端兼容性和安全要求。
TLS 1.3 简化了握手,在典型完整握手中比 TLS 1.2 少一次往返;它还定义了基于 PSK 的会话恢复。只有当客户端成功恢复会话,而且网关实例能够接受已签发的票据或状态时,这些改进才能降低建立连接的开销。
不要把 TLS 1.3 描述成固定百分比的延迟提升。客户端距离很近、连接已复用或应用本身很慢时,差异可能微乎其微;远距离客户端频繁新建连接时,收益才可能显著。
优化三:验证整个集群的会话恢复
RFC 8446 定义了 TLS 1.3 会话票据,客户端之后可将其作为预共享密钥使用。无需永远保持一条连接,会话恢复也能降低重连成本。
集群运行会带来一些关键问题:
- 一台实例签发的票据,在下一条连接到达另一台实例后能否使用?
- 票据加密密钥或服务端会话状态如何轮换和保护?
- 轮换能否保留可接受的重叠期,同时避免密钥寿命过长?
- 部署、扩容、跨区域故障转移或证书轮换期间会发生什么?
- 符合条件的握手中,真正恢复成功的比例是多少?
不要为了提高基准测试数字而牺牲密钥隔离。在范围过大的集群中共享票据密钥,会扩大密钥泄露的影响。应与安全负责人共同确定共享范围和轮换设计,再测量实际命中率。
把 0-RTT 视为独立的安全决策
TLS 1.3 早期数据通常称为 0-RTT,它与普通会话恢复不同。RFC 8446 说明,0-RTT 不具备普通应用数据同等的重放保证,因此需要防重放处理。网络攻击者可能导致已接收的早期数据被重放,而 TLS 层无法完全替应用阻止这种行为。
不要对创建订单、支付扣款、更改权限或其他无法安全重放的操作使用 0-RTT,除非有针对该应用的安全方案和经过测试的防重放设计。通过连接复用和普通会话恢复已经可以获得大部分连接效率收益,无需把会改变状态的应用请求作为早期数据发送。
优化四:提高证书传输效率
证书链会在完整握手期间发送,影响传输字节数、解析与验证。应使用正确的证书链:包含必需的中间证书,去掉无关或重复证书,并使用支持的客户端信任库进行测试。更小但不完整的证书链并不是优化。
证书与密钥的选择不仅影响性能,也涉及兼容性和安全性。只能在受支持客户端和合规要求的范围内比较。如果提供多种证书类型,要确认所有网关实例上的证书选择、SNI、Stapling 行为和监控都正常。
应自动续期证书并对过期进行告警。握手再快,如果偶尔返回过期、不匹配或不完整的证书,仍然是可用性事故。
配置 APISIX SSL 资源
Apache APISIX 使用 SSL 资源表示下游证书。当前 Admin API 文档支持证书、私钥、SNI 名称和 ssl_protocols 数组。
下面是可解析的 APISIX 3.18 模板。请通过密钥管理工作流用真实材料替换两个 PEM 占位符;切勿把私钥提交到源代码仓库。
1{
2 "cert": "-----BEGIN CERTIFICATE-----\n<server certificate and intermediates>\n-----END CERTIFICATE-----",
3 "key": "-----BEGIN PRIVATE KEY-----\n<private key from secret storage>\n-----END PRIVATE KEY-----",
4 "snis": ["api.example.com"],
5 "ssl_protocols": ["TLSv1.2", "TLSv1.3"]
6}在受控环境中通过 Admin API 应用该文件:
1curl "http://127.0.0.1:9180/apisix/admin/ssls/api-example" \
2 -X PUT \
3 -H "X-API-KEY: ${admin_key}" \
4 --data-binary @ssl.json
该资源只选择协议,并不是完整的性能配置。连接池、工作进程规模、监听器设置、会话行为,以及网关前的负载均衡器都取决于具体部署。应根据正在运行的 APISIX 和基础设施版本确认这些配置。
同时优化上游 TLS 区段
当 APISIX 代理到 HTTPS 上游时,客户端侧握手测量只反映一半路径。即使下游连接得到复用,如果网关为每个请求都创建新的上游 TLS 连接,仍可能耗费大量 CPU 并增加延迟。
应测量:
- 上游连接的创建与复用;
- 上游 TLS 握手延迟和失败;
- 上游证书验证和 SNI 正确性;
- Keep-Alive 连接池命中率和空闲连接淘汰;
- mTLS 证书查找与轮换行为;
- 上游节点的连接集中度。
不要通过禁用上游证书验证来降低延迟。应修复信任链、名称或连接池问题。如果网关与服务之间需要严格的身份验证,双向 TLS会增加客户端证书处理和运维状态,这些成本应纳入基准测试。
区分 CPU 饱和与网络延迟
握手延迟上升可能是因为数据包传输距离远,也可能是网关工作进程的 CPU 已饱和,两者的解决方法不同。
网络主导的信号包括:网关 CPU 保持稳定、延迟与客户端距离成比例,以及减少往返或就近终止连接后有所改善。CPU 主导的信号包括:运行队列变长、握手吞吐量不再增长,以及随着连接频繁建立,所有客户端区域的延迟都同时增加。
分析时应使用与生产环境相似的证书算法、插件链和流量组合。不要只测量空闲网关的 TLS 性能,再把结果套用到同时执行认证、日志记录、压缩和转换的网关。
横向扩容可以提升 CPU 容量,但如果新实例无法使用之前的会话状态,也可能降低恢复成功率。需要同时验证两方面效果。
通过保护措施逐步发布
- 为新建、复用和恢复连接建立基线。
- 每次只改一层:客户端复用、边缘到网关复用、网关到上游复用、协议或会话配置。
- 比较延迟百分位、每请求 CPU、握手速率、恢复成功率、连接错误和证书失败。
- 在真实客户端实现和网络路径上进行金丝雀发布。
- 测试轮换、实例替换和故障转移。
- 保留回滚路径,但回滚不能恢复已弃用的协议或不安全的验证设置。
除平均值外,还要关注错误预算。某项改动即使降低了握手延迟中位数,只要导致一小部分重要客户端失败,也不能算成功优化。
TLS 性能检查清单
- 是否分别测量了新建连接与持久连接?
- 每条客户端和上游连接承载多少请求?
- TLS 1.2 和 1.3 的选择是否符合策略并兼容受支持客户端?
- 经过负载均衡、部署和轮换后,会话恢复是否仍然成功?
- 0-RTT 是否被禁用,或只用于已经证明可安全防重放的操作?
- 证书链是否完整,而且没有不必要的体积?
- 成本模型是否包含上游 HTTPS 或 mTLS?
- 是否区分了 CPU、网络距离和应用延迟?
- 是否测试了故障转移与证书续期?
总结
API 网关的 TLS 性能首先是连接生命周期问题。应分别测量完整连接和稳定状态路径,复用网关两侧的连接,在真实集群拓扑下验证 TLS 1.3 与会话恢复,并将 0-RTT 重放风险与普通会话恢复分开处理。APISIX 可以终止现代 TLS 并管理证书,但最佳设置取决于客户端兼容性、拓扑、安全策略和实际观察到的连接行为。
常见问题
TLS 1.3 一定比 TLS 1.2 更快吗?
在常见完整握手中,它可以减少往返次数,但实际收益取决于网络距离、连接复用、客户端支持、会话恢复和应用延迟。应测量真实路径。
API 网关应该为提高性能启用 TLS 1.3 0-RTT 吗?
默认不应该。早期数据存在重放风险,需要应用专用的安全设计。普通连接复用和会话恢复通常是更安全的首选优化。
在网关终止 TLS 是否消除了所有 TLS 成本?
不会。网关仍需处理下游 TLS,还可能与上游建立另一条 TLS 或 mTLS 连接。两个区段都应纳入容量和延迟模型。
后续步骤
先为完整握手、连接复用和会话恢复建立基线,再确认当前版本支持的 APISIX SSL 资源字段。如需围绕 Apache APISIX 统一管理证书与策略,可以进一步了解 API7 Enterprise。
