RHEL Nginx SSL 与非 SSL 性能差异巨大。

are*_*cki 4 ssl http redhat nginx https

我正在设置 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
Run Code Online (Sandbox Code Playgroud)

基准测试客户端是 Apache bench,1 跳远,ping 1ms。Apache bench 在运行时使用以下 TLS 协议:

TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Run Code Online (Sandbox Code Playgroud)

服务器 SSL 证书 2048 位 RSA。OCSP 装订已打开并已验证。

/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
Run Code Online (Sandbox Code Playgroud)

/etc/security/limits.conf 有

nginx   soft    nofile  65536
nginx   hard    nofile  65536
Run Code Online (Sandbox Code Playgroud)

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

实际结果:

提供本地 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

代理到 Apache,1 毫秒 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Ste*_*ich 9

基准是谎言,不能反映现实,但可能是检测瓶颈的有用工具。但你必须了解基准。鉴于您忽略了了解基准测试结果所需的基本细节,您可能并不真正了解可能影响基准测试结果的因素。

尤其是有关测试负载大小的信息以及服务器和客户端的详细 CPU 负载信息缺失。因此,您可能已经达到客户端或服务器上的 CPU 限制。这也可能主要是请求所需的往返次数较多的问题。让我们更详细地解释 HTTP 与 HTTPS 的各个方面:

ab -c200 -n20000 http://SERVERNAME/localtest/index.html

您已配置为使用 200 个并发请求。请求的大小未知,因此我们可以假设只有最小的有效负载。您还没有使用 HTTP 保持活动状态,这意味着每个请求都会有一个新的 TCP 连接。我怀疑 apache bench 是否正在执行 TLS 会话恢复,以便每次都会进行完整的握手。这给了你:

  • HTTP:1 个 RTT 用于 TCP 握手,另一个 RTT 用于最小的 HTTP 请求和响应。这可能还包括连接已关闭(取决于实现)。这意味着 2 个 RTT 和最少的数据传输。
  • HTTPS 在此基础上添加:

    • 2 RTT 用于完整的 TLS 握手,可能还有 1 RTT 用于 TLS 关闭。仅仅因为 HTTPS 的总共 5 个 RTT 与普通 HTTP 的 2 个 RTT,您应该会看到性能大幅下降,即从大约 13000 req/s 到 5200 req/s(即 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 内核的性能。即使您使用多线程,计算仍然需要时间。使用openssl speed并不反映 TLS 握手中真正完成的操作,它也仅测试单个线程的最大速度,而不是并行的多个计算以及所有涉及的缓存清理等。

因此,虽然这可能是一个有趣的基准,以了解可能发生的情况,但在大多数情况下并不能反映现实。事实是 TLS 会大大降低性能,但是对于常见的 HTTP 流量,您将有更大的请求、HTTP 保持活动和 TLS 会话重用,这些都减少了代价高昂的 TLS 握手的影响。

但是,如果基准测试实际上仅限于服务器性能而不是客户端性能,则设置可能会反映用于跟踪的服务器,您可能只有来自许多不同站点的很小响应(即 1x1 像素)而没有任何类型的 TLS 会话重用或 HTTP 保持活动状态。