HTTPS 双向认证在压测时 CPU 增加 50%,如何优化 TLS 会话复用

解读

面试官把“CPU 暴涨 50%”和“双向 TLS”绑定提问,核心想验证三件事:

  1. 能否把性能衰减准确归因到 TLS 握手环节,而不是拍脑袋说“加解密开销大”;
  2. 是否熟悉国密、RSA/ECC 证书链、OCSP、CRL 等在国内生产环境落地的差异;
  3. 能否给出可量化的复用策略,并配套监控、压测验证、灰度回滚方案。
    回答时要先定位瓶颈→再谈复用→最后给出落地闭环,避免只背“开启 session reuse”一句话。

知识点

  1. 双向 TLS 握手多两次证书验证 + 一次 CertificateVerify,RSA 2048 完整握手 CPU 消耗约为单向 2.3 倍,ECC 256 约为 1.8 倍。
  2. TLS 1.2/1.3 会话复用机制:Session ID、Session Ticket、PSK(0-RTT)、Keyless SSL、国密 SSLVPN 的 SCF 规范。
  3. 国密场景下 SM2 签名验签比 ECDSA P-256 慢 3~4 倍,SM3/SM4 硬件加速卡(阿里云加密计算、华为 Kunpeng 加速引擎)可降 30% CPU。
  4. 压测侧指标:handshake/s、full handshake 占比、SSL/TLS 握手延迟(ssl_handshake_time)、CPU 内核态占比、QAT/AVX 指令利用率。
  5. 复用失效根因:多节点 Ticket 密钥不一致、CDN 边缘节点漂移、SLB 四层调度哈希变化、压测脚本未带 SNI、证书链包含 OCSP Must-Staple。
  6. 国内合规:金融、运营商要求国密双证,必须走商密产品认证;若使用海外 TLS 1.3 0-RTT,需关闭 0-RTT 或经国密办评估,防止重放风险。

答案

“我在 XX 支付网关压测也遇到过同样现象,CPU 从 35% 飙到 53%,定位过程分四步:
第一步,用 perf + ebpf 火焰图确认热点,发现 48% CPU 落在 rsa_ossl_private_decryptx509_verify_cert;再抓 10w 样本,full handshake 占比 92%,确认复用失败。
第二步,排查复用失效原因:

  1. 7 层 SLB 后面 12 台 Envoy,ticket 密钥未做分布式同步,导致客户端每次落到不同实例就回退到 full handshake;
  2. 压测脚本 JMeter 默认把“Same user on each iteration”勾上,TCP 连接被强制断开,Session ID 无法复用;
  3. 证书链带了 OCSP Must-Staple,Envoy 没配置 stapling,每次握手阻塞 30 ms 去 OCSP 站点拉取。
    第三步,优化手段:
  4. 统一 Ticket 密钥:用 Kubernetes Secret 做密钥池,每 6 小时轮转,Envoy 热更新,保证 12 实例密钥一致;
  5. 打开 Session Cache,缓存 20480 条,超时 300 s,内存占用约 200 MB;
  6. 压测脚本侧把 HTTP 连接池 maxConnectionsPerHost 调到 500,CookieManager 关闭,确保长连接 + 同一线程复用;
  7. 开启 OCSP Stapling,把 staples 文件预生成到本地盘,握手不再实时联网;
  8. 国密环境用 SM2 加速卡,把私钥签名卸载到 Kunpeng 920 内置加速引擎,单核 handshake 能力从 1100 次/s 提到 3100 次/s;
  9. 灰度验证:先 5% 流量,对比 CPU、handshake/s、P99 延迟,确认无误后全量。
    第四步,效果:full handshake 占比降到 6%,CPU 回落 38%,整体 QPS 提升 42%,满足双十一 8w tps 目标。后续把 TLS 1.3 PSK 排入迭代,可再降 15% 延迟。”

拓展思考

  1. 如果业务强制国密且要求 FIPS 140-3 模块,如何同时满足商密型号与 TLS 1.3 的 PSK?
  2. 在 Service Mesh 东西向流量全量双向 TLS 场景,Sidecar 内存暴涨,如何评估 Session Cache 大小与驱逐策略?
  3. 0-RTT 带来重放攻击面,国内监管尚未放行,若未来放开,压测脚本如何构造合法 anti-replay token?
  4. 当证书链深度 ≥3 且含交叉证书,如何量化验证时 CPU 随链长线性增长的系数,并在容量模型里预留算力?