![RHEL Nginx SSL 与非 SSL 性能差异巨大。](https://linux22.com/image/676426/RHEL%20Nginx%20SSL%20%E4%B8%8E%E9%9D%9E%20SSL%20%E6%80%A7%E8%83%BD%E5%B7%AE%E5%BC%82%E5%B7%A8%E5%A4%A7%E3%80%82.png)
我正在设置 Nginx 1.8 反向代理。
简而言之 -
提供 HTML 内容 HTTP 流量比 HTTPS 快 50 倍。
提供 ProxyPass HTTP 流量比提供 HTTPS 流量快 7 倍。
操作系统是 RHEL7
硬件:
2 core VMWare Intel(R) Xeon(R) CPU E5-2609 v3 @ 1.90GHz
cpu MHz : 1897.802
cache size : 15360 KB
bogomips : 3795.60
1 Gbit network card
基准测试客户端是 Apache bench,距离 1 跳,ping 1ms。Apache bench 在运行时使用以下 TLS 协议:
TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
服务器 SSL 证书 2048 位 RSA。OCSP Stapling 已开启并已验证。
/etc/sysctl.conf 有
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=15
net.core.netdev_max_backlog=4096
net.core.rmem_max=16777216
net.core.somaxconn=4096
net.core.wmem_max=16777216
net.ipv4.tcp_max_syn_backlog=20480
net.ipv4.tcp_max_tw_buckets=400000
net.ipv4.tcp_no_metrics_save=1
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_syn_retries=2
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_wmem=4096 65536 16777216
vm.min_free_kbytes=65536
/etc/security/limits.conf 有
nginx soft nofile 65536
nginx hard nofile 65536
Nginx 配置为
server {
listen 443 ssl deferred backlog=1024;
listen 80 deferred backlog=1024;
server_name SERVERNAME;
client_max_body_size 10m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate path_to_/certificateAndChain.cer;
ssl_certificate path_to_/certificateAndChain.cer;
ssl_certificate_key path_to_/private.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AES:EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:AES128+EECDH:D$
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:32m;
ssl_session_timeout 1m;
#resolver 8.8.8.8 8.8.8.4 valid=1m;
#resolver_timeout 5s;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 43200000;
proxy_read_timeout 43200000;
proxy_send_timeout 43200000;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://IPADDRESS/;
}
location /localtest {
root /var/www/localtest;
index index.html;
}
}
实际结果:
提供本地 HTML 内容 HTTP
ab -c200 -n20000 http://SERVERNAME/localtest/index.html
Requests per second: 12751.64 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 4 2.3 4 11
Processing: 2 12 7.3 9 96
Waiting: 1 10 7.7 7 96
Total: 2 16 6.6 14 100
HTTPS:
Requests per second: 252.28 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 12 651 288.1 694 1470
Processing: 0 141 134.4 101 1090
Waiting: 0 101 124.3 65 1089
Total: 15 792 276.7 809 1641
代理到 Apache,1ms ping,1 跳距离。
HTTP
Requests per second: 1584.88 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 2.3 1 8
Processing: 4 141 309.6 30 1244
Waiting: 4 141 309.7 29 1244
Total: 10 143 310.3 31 1248
HTTPS
Requests per second: 215.99 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 14 1131 622.3 1137 2030
Processing: 4 474 413.2 313 1814
Waiting: 1 399 405.6 257 1679
Total: 26 1605 769.6 1699 3306
答案1
基准测试是谎言,不能反映现实,但可能是检测瓶颈的有用工具。但您必须了解基准测试。鉴于您忽略了理解基准测试结果所需的基本细节,您可能并不真正了解可能影响基准测试结果的因素。
尤其是缺少有关测试负载大小的信息以及服务器和客户端的详细 CPU 负载信息。因此,可能是您已经达到客户端或服务器上的 CPU 限制。这也可能主要是请求需要更多往返的问题。让我们更详细地解释 HTTP 与 HTTPS 的各个方面:
ab-c200-n20000http://服务器名称/localtest/index.html
您已配置为使用 200 个并发请求。请求的大小未知,因此我们可以假设只有最小的有效负载。您还未使用 HTTP 保持活动,这意味着每个请求都会有一个新的 TCP 连接。我怀疑 apache bench 是否正在执行 TLS 会话恢复,以便每次都会有完整的握手。这为您提供:
- HTTP:1 RTT 用于 TCP 握手,另一个 RTT 用于最小 HTTP 请求和响应。这可能还包括已关闭的连接(取决于实现)。这意味着 2 RTT 和最小数据传输。
HTTPS 在此基础上添加了:
- 完整的 TLS 握手需要 2 RTT,TLS 关闭可能也需要 1 RTT。由于 HTTPS 总共需要 5 RTT,而普通 HTTP 需要 2 RTT,因此您应该会看到性能大幅下降,即从大约 13000 个请求/秒下降到 5200 个请求/秒(即 2/5)。
- 仅 TLS 握手所传输的数据甚至可能比您在简单的 HTTP 请求中作为有效负载的数据还要大(编辑:根据建议,您的响应大小从 60 字节到 50kb 不等,所以这可能不太相关)。
- 但是,在客户端和服务器端,TLS 握手也需要大量计算。由于您使用的是 ECDHE,因此需要进行更多计算,请参阅https://securitypitfalls.wordpress.com/2014/10/06/rsa-and-ecdsa-performance/。
TLS 握手期间的计算需要大量的 CPU 时间,因此提供有关 CPU 负载的信息非常重要。可能您只是在服务器或客户端达到了 CPU 可以执行的最大值。另请注意,apache bench 是单线程的,因此即使其他 CPU 核心处于空闲状态,也足以最大限度地发挥单个 CPU 核心的性能。即使您使用多个线程,计算仍然需要时间。使用并openssl speed
不能反映 TLS 握手中实际完成的工作,而且它只测试单个线程的最大速度,而不是并行进行多个计算以及涉及的所有缓存破坏等。
因此,虽然这可能是一个有趣的基准,可以看看什么是可能的,但它在大多数情况下并不反映现实。事实上,TLS 可以大大降低性能,但对于常见的 HTTP 流量,您将拥有更大的请求、HTTP 保持活动和 TLS 会话重用,所有这些都可以减少昂贵的 TLS 握手的影响。
但是,如果基准测试实际上仅限于服务器性能而不是客户端性能,则设置可能会反映用于跟踪的服务器,其中您可能只有来自许多不同站点的少量响应(即 1x1 像素)而没有任何类型的 TLS 会话重用或 HTTP 保持活动。
答案2
由于 TLS 协商,第一个 https 请求确实比较慢,并且您的基准测试仅对此进行了测试。
现实生活中的客户端会发出很多请求(一个用于 html 页面,几个用于 js/css/images)。
使用 TLS 会话票证,在第一个请求后将跳过该 TLS 协商。
在会话票证过期之前,https 请求会比 http 慢一点。但是,如果您使用 SPDY 或 HTTP2,则 https 会比 http 快。