高性能 Nginx HTTPS 调优 - 这样配置让HTTPS 提速 30%
Nginx 常作为最常见的服务器,常被用作负载均衡 (Load Balancer)、反向代理 (Reverse Proxy),以及网关 (Gateway) 等等。一个配置得当的 Nginx 服务器单机应该可以期望承受住 50K 到 80K 左右每秒的请求,同时将 CPU 负载在可控范围内。
这篇文章中,我们先介绍 Nginx 中的 TLS 设置有哪些与请求延迟可能相关,如何调整才能最大化加速。
TLS 握手和延迟
下图中展示了如果你的服务启用了 HTTPS,在开始传输任何数据之前的数据传输情况。
假设每次来回需要 28 毫秒的话,用户已经等了 224 毫秒之后才开始接收数据。
同时这个 28 毫秒其实是非常乐观的假设,在国内电信、联通和移动以及各种复杂的网络状况下,用户与服务器之间的延迟更不可控。另一方面,通常一个网页需要数十个请求,这些请求不一定可以全部并行,因此几十乘以 224 毫秒,页面打开可能就是数秒之后了。
所以,原则上如果可能的话,我们需要尽量减少用户和服务器之间的往返程 (roundtrip),在下文的设置中,对于每个设置我们会讨论为什么这个设置有可能帮助减少往返程。
Nginx 中的 TLS 设置
开启 HTTP/2
HTTP/2 标准是从 Google 的 SPDY 上进行的改进,比起 HTTP 1.1 提升了不少性能,尤其是需要并行多个请求的时候可以显著减少延迟。
在 Nginx 中开启 HTTP 2.0 非常简单,只需要增加一个 http2 标志即可
listen 443 ssl;
# 改为
listen 443 ssl http2;
如何确认你的网站或者 API 开启了 HTTP 2
在 Chrome 中打开开发者工具,点开 Protocol 之后在所有的请求中都可以看到请求用的协议了。如果 protocol 这列的值是 h2 的话,那么用的就是 HTTP 2 了
当然另一个办法是直接用 curl 如果返回的 status 前有 HTTP/2 的话自然也就是 HTTP/2 开启了。
调整 Cipher 优先级
尽量挑选更新更快的 Cipher,有助于减少延迟:
# 手动启用 cipher 列表
ssl_prefer_server_ciphers on; # prefer a list of ciphers to prevent old and slow ciphers
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
启用 OCSP Stapling
在国内这可能是对使用 Let's Encrypt 证书的服务或网站影响最大的延迟优化了。如果不启用 OCSP Stapling 的话,在用户连接你的服务器的时候,有时候需要去验证证书。而因为一些不可知的原因(这个就不说穿了)Let's Encrypt 的验证服务器并不是非常通畅,因此可以造成有时候数秒甚至十几秒延迟的问题,这个问题在 iOS 设备上特别严重
解决这个问题的方法有两个:
-
不使用 Let's Encrypt,可以尝试替换为阿里云提供的免费 DV 证书
-
开启 OCSP Stapling
开启了 OCSP Stapling 的话开启了 OCSP Stapling 的话,跑到证书验证这一步可以省略掉。省掉一个 roundtrip,特别是网络状况不可控的 roundtrip,可能可以将你的延迟大大减少。
在 Nginx 中启用 OCSP Stapling 也非常简单,只需要设置:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/full_chain.pem;
# 如何检测 OCSP Stapling 是否已经开启?
openssl s_client -connect 518wz.top:443 -servername kalasearch.cn -status -tlsextdebug < /dev/null 2>&1 | grep -i "OCSP response"
# 结果为如下,表明已经开启。
OCSP response:
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
调整 ssl_buffer_size
sslbuffersize 控制在发送数据时的 buffer 大小,默认设置是 16k。这个值越小,则延迟越小,而添加的报头之类会使 overhead 会变大,反之则延迟越大,overhead 越小。
因此如果你的服务是 REST API 或者网站的话,将这个值调小可以减小延迟和 TTFB,但如果你的服务器是用来传输大文件的,那么可以维持 16k。
如果是网站或者 REST API,建议值为 4k,但是这个值的最佳取值显然会因为数据的不同而不一样,因此请尝试 2 - 16k 间不同的值。在 Nginx 中调整这个值也非常容易
sl_buffer_size 4k;
启用 SSL Session 缓存
启用 SSL Session 缓存可以大大减少 TLS 的反复验证,减少 TLS 握手的 roundtrip。虽然 session 缓存会占用一定内存,但是用 1M 的内存就可以缓存 4000 个连接,可以说是非常非常划算的。同时,对于绝大多数网站和服务,要达到 4000 个同时连接本身就需要非常非常大的用户基数,因此可以放心开启。
这里 ssl_session_cache 设置为使用 50M 内存,以及 4 小时的连接超时关闭时间 ssl_session_timeout
# Enable SSL cache to speed up for return visitors
ssl_session_cache shared:SSL:50m; # speed up first time. 1m ~= 4000 connections
ssl_session_timeout 4h;
本文链接:https://www.518wz.top/post/30.html 转载需授权!