不能依赖 $ssl_session_id 判断复用率,因其仅表示客户端携带 Session ID,不反映实际复用成功;应使用 $ssl_session_reused(直连)或 $upstream_ssl_session_reused(代理)准确衡量 TLS 会话复用效果及 CPU 握手优化程度。

直接用 $ssl_session_id 分析复用率会得出错误结论——它只表示客户端在 ClientHello 中携带了 Session ID 字段,不反映实际是否成功复用。真正能准确衡量 TLS 会话复用效果、进而评估 CPU 握手开销优化程度的,是 $ssl_session_reused(客户端直连场景)或 $upstream_ssl_session_reused(代理后端场景)。
为什么不能依赖 $ssl_session_id
- 客户端可能每次连接都带上旧 ID(比如 App 启动时缓存未清),但服务端早已过期或未命中缓存;
- Nginx 可能收到 ID 却因缓存满、超时、worker 不共享等原因拒绝复用;
- 日志中
$ssl_session_id非空 ≠ 复用成功,甚至和$ssl_session_reused值为.(新建)同时出现; - 单纯统计非空 ID 数量,容易高估复用率 20%–50%,误导调优方向。
正确采集复用状态的日志格式
在 http { } 块中定义日志格式,包含真实复用标识:
log_format ssl_reuse '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'ssl_reused=$ssl_session_reused '
'upstream_ssl_reused=$upstream_ssl_session_reused '
'ssl_session_id="$ssl_session_id"';再按使用场景启用:
- 若 Nginx 自身提供 HTTPS 服务(如前端网站),在
server块中写:access_log /var/log/nginx/https_access.log ssl_reuse; - 若 Nginx 代理 HTTPS 后端(如调用微服务),在
location块中写:access_log /var/log/nginx/proxy_access.log ssl_reuse;
用日志统计真实复用率
采集 1 小时日志后,用 awk 快速计算:
# 统计客户端到 Nginx 的复用率(关注第 9 字段,即 ssl_reused= 值)
awk '$9 ~ /r/ {r++} $9 ~ /\./ {d++} END {printf "client reuse rate: %.1f%\n", r/(r+d)*100}' /var/log/nginx/https_access.log
# 统计 Nginx 到 upstream 的复用率(关注第 10 字段,即 upstream_ssl_reused= 值)
awk '$10 ~ /r/ {r++} $10 ~ /\./ {d++} END {printf "upstream reuse rate: %.1f%\n", r/(r+d)*100}' /var/log/nginx/proxy_access.log✅ 健康阈值参考:
- Web 页面类业务:
$ssl_session_reused = r比例建议 ≥ 70%;- 移动端长连接或 API 网关:≥ 85% 更合理;
- 若长期低于 60%,说明缓存配置失效或容量不足,CPU 握手开销未被有效缓解。
结合复用率反推 CPU 性能收益
TLS 完整握手比复用握手多消耗约 70% 的 CPU 时间(主要来自密钥交换与证书验证)。若复用率从 40% 提升至 80%,意味着每 100 次连接中,完整握手从 60 次降至 20 次——CPU 在 TLS 层的计算负载可下降约 55%。
这不是理论值:实测中,Nginx worker 进程的 sy(系统态 CPU)占比常随复用率上升明显回落,尤其在高并发静态资源或 WebSocket 场景下。
配置不生效?快速定位三类常见原因
-
缓存没放对位置:
ssl_session_cache shared:SSL:10m;必须写在http { }块顶层,写进server或location里等于无效; -
缓存太小或超时太短:日均 UV 50 万以上站点,建议起步
shared:SSL:20m + ssl_session_timeout 20m; -
没开 session ticket 兜底:仅靠缓存抗不住突发流量,必须配
ssl_session_tickets on;和ssl_session_ticket_key,否则缓存满后全部退化为全握手。
不复杂但容易忽略。



















