高性能 Nginx HTTPS 调优 - 如何为 HTTPS 提速 30%

做者 | 卡拉先生java

来源 | https://kalasearch.cn/blog/high-performance-nginx-tls-tuning/

为何要优化 Ngin HTTPS 延迟

Nginx 常做为最多见的服务器,常被用做负载均衡 (Load Balancer)、反向代理 (Reverse Proxy),以及网关 (Gateway) 等等。一个配置得当的 Nginx 服务器单机应该能够指望承受住 50K 到 80K 左右每秒的请求,同时将 CPU 负载在可控范围内。nginx

但在不少时候,负载并非须要首要优化的重点。好比对于卡拉搜索来讲,咱们但愿用户在每次击键的时候,能够体验即时搜索的感受,也就是说,每一个搜索请求必须在 100ms - 200ms 的时间内端对端地返回给用户,才能让用户搜索时没有“卡顿”和“加载”。所以,对于咱们来讲,优化请求延迟才是最重要的优化方向。web

这篇文章中,咱们先介绍 Nginx 中的 TLS 设置有哪些与请求延迟可能相关,如何调整才能最大化加速。而后咱们用优化Nginx 服务器的实例来分享如何调整 Nginx TLS/SSL 设置,为首次搜索的用户提速 30% 左右。咱们会详细讨论每一步咱们作了一些什么优化,优化的动机和效果。但愿能够对其它遇到相似问题的同窗提供帮助。浏览器

TLS 握手和延迟

不少时候开发者会认为:若是不是绝对在乎性能,那么了解底层和更细节的优化没有必要。这句话在不少时候是恰当的,由于不少时候复杂的底层逻辑必须包起来,才能让更高层的应用开发复杂度可控。好比说,若是你就只须要开发一个 APP 或者网站,可能并无必要关注汇编细节,关注编译器如何优化你的代码——毕竟在苹果或者安卓上不少优化在底层就作好了。缓存

那么,了解底层的 TLS 和应用层的 Nginx 延迟优化有什么关系呢?安全

答案是多数状况下,优化网络延迟实际上是在尝试减小用户和服务器之间的数据传输次数,也就是所谓的 roundtrip。因为物理限制,北京到云南的光速传播差很少就是要跑 20 来毫秒,若是你不当心让数据必须屡次往返于北京和云南之间,那么必然延迟就上去了。服务器

所以若是你须要优化请求延迟,那么了解一点底层网络的上下文则会大有裨益,不少时候甚至是你是否能够轻松理解一个优化的关键。本文中咱们不深刻讨论太多 TCP 或者 TLS 机制的细节,若是有兴趣的话请参考 High Performance Browser Networking 一书,能够免费阅读。微信

举个例子,下图中展现了若是你的服务启用了 HTTPS,在开始传输任何数据以前的数据传输状况。网络

在传输数据前数据已经跑了好几个来回 roundtrip

能够看到,在你的用户拿到他须要的数据前,底层的数据包就已经在用户和你的服务器之间跑了 3 个来回。session

假设每次来回须要 28 毫秒的话,用户已经等了 224 毫秒以后才开始接收数据。

同时这个 28 毫秒实际上是很是乐观的假设,在国内电信、联通和移动以及各类复杂的网络情况下,用户与服务器之间的延迟更不可控。另外一方面,一般一个网页须要数十个请求,这些请求不必定能够所有并行,所以几十乘以 224 毫秒,页面打开可能就是数秒以后了。

因此,原则上若是可能的话,咱们须要尽可能减小用户和服务器之间的往返程 (roundtrip),在下文的设置中,对于每一个设置咱们会讨论为何这个设置有可能帮助减小往返程。

Nginx 中的 TLS 设置

那么在 Nginx 设置中,怎样调整参数会减小延迟呢?

开启 HTTP/2

HTTP/2 标准是从 Google 的 SPDY 上进行的改进,比起 HTTP 1.1 提高了很多性能,尤为是须要并行多个请求的时候能够显著减小延迟。在如今的网络上,一个网页平均须要请求几十次,而在 HTTP 1.1 时代浏览器能作的就是多开几个链接(一般是 6 个)进行并行请求,而 HTTP 2 中能够在一个链接中进行并行请求。HTTP 2 原生支持多个并行请求,所以大大减小了顺序执行的请求的往返程,能够首要考虑开启。

若是你想本身看一下 HTTP 1.1 和 HTTP 2.0 的速度差别,能够试一下:https://www.httpvshttps.com/。个人网络测试下来 HTTP/2 比 HTTP 1.1 快了 66%。

HTTP 1.1 与 HTTP 2.0 速度对比

在 Nginx 中开启 HTTP 2.0 很是简单,只须要增长一个 http2 标志便可

listen 443 ssl;

# 改成
listen 443 ssl http2;

若是你担忧你的用户用的是旧的客户端,好比 Python 的 requests,暂时还不支持 HTTP 2 的话,那么其实不用担忧。若是用户的客户端不支持 HTTP 2,那么链接会自动降级为 HTTP 1.1,保持了后向兼容。所以,全部使用旧 Client 的用户,仍然不受影响,而新的客户端则能够享受 HTTP/2 的新特性。

如何确认你的网站或者 API 开启了 HTTP 2

在 Chrome 中打开开发者工具,点开 Protocol 以后在全部的请求中均可以看到请求用的协议了。若是 protocol 这列的值是 h2 的话,那么用的就是 HTTP 2 了

用 Chrome 确认 HTTP/2 已经打开

固然另外一个办法是直接用 curl 若是返回的 status 前有 HTTP/2 的话天然也就是 HTTP/2 开启了。

➜  ~ curl --http2 -I https://kalasearch.cn
HTTP/2 403
server: Tengine
content-type: application/xml
content-length: 264
date: Tue, 22 Dec 2020 18:38:46 GMT
x-oss-request-id: 5FE23D363ADDB93430197043
x-oss-cdn-auth: success
x-oss-server-time: 0
x-alicdn-da-ups-status: endOs,0,403
via: cache13.l2et2[148,0], cache10.l2ot7[291,0], cache4.us13[360,0]
timing-allow-origin: *
eagleid: 2ff6169816086623266688093e

调整 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 设备上特别严重

解决这个问题的方法有两个:

  1. 不使用 Let's Encrypt,能够尝试替换为阿里云提供的免费 DV 证书
  2. 开启 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 test.kalasearch.cn: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

则代表已经开启。参考 HTTPS 在 iPhone 上慢的问题 一文

调整 ssl_buffer_size

sslbuffersize 控制在发送数据时的 buffer 大小,默认设置是 16k。这个值越小,则延迟越小,而添加的报头之类会使 overhead 会变大,反之则延迟越大,overhead 越小。

所以若是你的服务是 REST API 或者网站的话,将这个值调小能够减少延迟和 TTFB,但若是你的服务器是用来传输大文件的,那么能够维持 16k。关于这个值的讨论和更通用的 TLS Record Size 的讨论,能够参考:Best value for nginx's sslbuffersize option

若是是网站或者 REST API,建议值为 4k,可是这个值的最佳取值显然会由于数据的不一样而不同,所以请尝试 2 - 16k 间不一样的值。在 Nginx 中调整这个值也很是容易

ssl_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;

卡拉搜索如何减小 30% 的请求延迟

卡拉搜索是国内的 Algolia,致力于帮助开发者快速搭建即时搜索功能(instant search),作国内最快最易用的搜索即服务。

开发者接入后,全部搜索请求经过卡拉 API 便可直接返回给终端用户。为了让用户有即时搜索的体验,咱们须要在用户每次击键后极短的时间内(一般是 100ms 到 200ms)将结果返回给用户。所以每次搜索须要能够达到 50 毫秒之内的引擎处理时间和 200 毫秒之内的端对端时间。

咱们用豆瓣电影的数据作了一个电影搜索的 Demo,若是感兴趣的话欢迎体验一下即时搜索,尝试一下搜索“无间道”或者“大话西游”体验一下速度和相关度:https://movies-demo.kalasearch.cn/

对于每一个请求只有 100 到 200 毫秒的延迟预算,咱们必须把每一步的延迟都考虑在内。

简化一下,每一个搜索请求须要经历的延迟有

卡拉搜索的端对端延迟图示

总延迟 = 用户请求到达服务器(T1) + 反代处理(Nginx T2) + 数据中心延迟(T3) + 服务器处理 (卡拉引擎 T4) + 用户请求返回(T3+T1)

在上述延迟中,T1 只与用户与服务器的物理距离相关,而 T3 很是小(参考Jeff Dean Number)能够忽略不计。

因此咱们能控制的大体只有 T2 和 T4,即 Nginx 服务器的处理时间和卡拉的引擎处理时间。

Nginx 在这里做为反向代理,处理一些安全、流量控制和 TLS 的逻辑,而卡拉的引擎则是一个在 Lucene 基础上的倒排引擎。

咱们首先考虑的第一个可能性是:延迟是否是来自卡拉引擎呢?

在下图展现的 Grafana 仪表盘中,咱们看到除了几个时不时的慢查询,搜索的 95% 服务器处理延迟小于 20 毫秒。对比一样的数据集上 benchmark 的 Elastic Search 引擎的 P95 搜索延迟则在 200 毫秒左右,因此排除了引擎速度慢的可能。

Search Grafana

而在阿里云监控中,咱们设置了从全国各地向卡拉服务器发送搜索请求。咱们终于发现 SSL 处理时间时常会超过 300 毫秒,也就是说在 T2 这一步,光处理 TLS 握手之类的事情,Nginx 已经用掉了咱们全部的请求时间预算。

同时检查以后咱们发现,在苹果设备上搜索速度格外慢,特别是第一次访问的设备。所以咱们大体判断应该是由于咱们使用的 Let's Encrypt 证书的问题。

咱们按照上文中的步骤对 Nginx 设置进行了调整,并将步骤总结出来写了这篇文章。在调整了 Nginx TLS 的设置后,SSL 时间从平均的 140ms 下降到了 110ms 左右(全国全部省份联通和移动测试点),同时苹果设备上首次访问慢的问题也消失了。

调整后延迟

在调整事后,全国范围内测试的搜索延迟下降到了 150 毫秒左右。

总结

调整 Nginx 中的 TLS 设置对于使用 HTTPS 的服务和网站延迟有很是大的影响。本文中总结了 Nginx 中与 TLS 相关的设置,详细讨论各个设置可能对延迟的影响,并给出了调整建议。以后咱们会继续讨论 HTTP/2 对比 HTTP 1.x 有哪些具体改进,以及在 REST API 使用 HTTP/2 有哪些优缺点,请继续关注




本文分享自微信公众号 - 肥朝(feichao_java)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索