多实例会话恢复一致性
TLS 会话恢复能让客户端跳过完整握手,但在集群里有个特有的坑:会话票据由服务端密钥加密,如果每个实例各自生成密钥,客户端从 A 实例拿到票据、下次连到 B 实例就会解密失败,只能回退到完整握手。表现是同一客户端访问耗时忽高忽低、复用率偏低。解决办法是让所有实例共享同一份票据密钥(同步加载并定期轮换),或改用集中式会话缓存。
基本信息
| Session Ticket | 密钥需在所有实例一致:同一文件同步加载并定期轮换 |
|---|---|
| Session ID 缓存 | ssl_session_cache 是各实例本地内存,跨实例无效 |
| 观察手段 | s_client -reconnect 观察 New 与 Reused 计数 |
| 轮换方式 | 先增加新密钥再移除旧密钥,保证存量票据仍能解开 |
| 影响 | 复用率低会推高 CPU 与握手延迟,但通常不影响功能可用性 |
典型使用场景
- 集群复用率偏低排查:P95 延迟不稳、CPU 偏高但流量正常
- 多实例部署后的性能回归验证
- 滚动发布期间票据密钥的平滑轮换
- 多机房与混合云场景确认各区域是否共享同一份密钥
- 票据密钥的权限治理:与私钥同级管理并纳入轮换计划
验证复用与共享配置
验证复用与共享配置
openssl s_client -connect example.com:443 -servername example.com -reconnect </dev/null 2>&1 | grep -E 'New|Reused' | head -8
# 多次握手应出现 Reused;全是 New 说明恢复未生效
nginx 多实例共享票据密钥
nginx 多实例共享票据密钥
ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ticket.key.current; # 所有实例加载同一份
ssl_session_ticket_key /etc/nginx/ticket.key.previous; # 轮换过渡期保留旧密钥
ssl_session_cache shared:SSL:10m; # 本实例共享内存缓存票据密钥泄漏会使相关会话流量可被解密:密钥文件权限按私钥标准收紧,分发走受控通道,不要打进镜像层或提交到代码仓库。
观测建议:按实例统计复用率,如果各实例数值差异明显,多半是票据密钥未同步,或会话保持策略把客户端固定到了同一台后端;配合 P95 握手耗时一起看,比单独看复用率更容易定位。