开启 HTTPS 后响应变慢通常是因为 SSL 握手消耗了额外 CPU 和时间,优化会话缓存能让重复访问的用户跳过完整握手,从而降低延迟。
先说结论:优先调整 ssl_session_cache 和 ssl_session_timeout,在保障安全的前提下减少握手次数。
- 先定位:检查当前 Nginx 配置是否已启用会话缓存及超时设置。
- 先做:配置共享内存缓存并合理设置超时时间,避免频繁握手。
- 再验证:通过 OpenSSL 保存和加载会话文件确认复用是否生效,观察 CPU 使用率变化。
为什么会这样
HTTPS 建立连接时需要经过 SSL 握手,这个过程涉及非对称加密计算,比普通的 HTTP 请求更消耗服务器 CPU 资源。如果每个请求都进行完整握手,高并发下响应就会变慢。SSL 会话缓存允许客户端和服务器在后续连接中复用之前的会话参数,跳过部分握手步骤,从而减少计算开销和延迟。
完整配置示例
将会话缓存配置放在 http 块或 server 块中。建议使用共享内存模式,以便多个 worker 进程共用。以下是包含必要上下文的 server 块配置示例:
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 启用共享内存缓存,10m 可存储约 40000 个会话
ssl_session_cache shared:SSL:10m;
# 会话超时时间,建议设置为 1 天
ssl_session_timeout 1d;
# 会话票据设置,开启可提升复用率但需注意密钥轮换
ssl_session_tickets on;
location / {
root /usr/share/nginx/html;
index index.html;
}
}注意:修改配置前请先备份原文件,修改后使用 nginx -t 测试语法,确认无误后使用 nginx -s reload 重载服务。
验证会话复用是否生效
Nginx 默认 access.log 不记录 SSL 握手细节,需使用 OpenSSL 工具分步验证。第一次连接保存会话文件,第二次连接加载该文件。
1. 第一次连接,保存会话到文件:
openssl s_client -connect yourdomain.com:443 -sess_out session.pem2. 第二次连接,加载会话文件:
openssl s_client -connect yourdomain.com:443 -sess_in session.pem3. 观察输出结果。如果配置生效,第二次连接输出中应显示会话复用迹象(如 Session-ID 一致或握手过程简化)。也可使用 tcpdump 或 Wireshark 抓包,观察第二次握手是否省略了 Certificate 交换等步骤。
同时观察服务器 CPU 使用率,在相同流量下,优化后 CPU 峰值应有所平缓。通常可降低握手开销,具体提升取决于业务请求频率和会话复用率。
常见坑与安全建议
- 缓存大小设置过小会导致频繁淘汰,过大则浪费内存。10m 是常见参考值,可根据并发量调整。
- 多 worker 模式下,若不使用 shared 缓存,各进程缓存不互通,会降低复用率。
- ssl_session_tickets 开启后若未配置密钥轮换存在前向安全性风险。生产环境建议配合自动化脚本定期轮换密钥,或对安全性要求极高时关闭该选项。
参考来源
- Nginx 官方文档,ngx_http_ssl_module,https://nginx.org/en/docs/http/ngx_http_ssl_module.html