Nginx

RHEL Nginx SSL 與非 SSL 的性能差異巨大。

  • February 7, 2016

我正在設置 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 裝訂已打開並已驗證。

/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,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

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

基準是謊言,不反映現實,但可能是檢測瓶頸的有用工具。但是您必須了解基準。鑑於您省略了了解基準測試結果所需的基本細節,您可能並不真正了解可能影響基準測試結果的因素。

尤其是有關測試有效負載大小的資訊以及伺服器和客戶端的詳細 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 核心處於空閒狀態,也足以最大限度地發揮單個 CPU 核心的性能。即使您使用多執行緒,計算仍然需要時間。使用openssl speed並不能反映 TLS 握手中的實際操作,它還僅測試單個執行緒的最大速度,而不是並行計算多個計算以及涉及的所有記憶體垃圾等。

因此,雖然這可能是一個有趣的基準,可以看到什麼是可能的,但在大多數情況下它並不能反映現實。事實是 TLS 會大大降低性能,但是對於常見的 HTTP 流量,您將擁有更大的請求、HTTP 保持活動和 TLS 會話重用,這些都減少了代價高昂的 TLS 握手的影響。

但是,如果基準實際上受限於伺服器性能而不是客戶端性能,則設置可能會反映用於跟踪的伺服器,在這種情況下,您可能只有來自許多不同站點的很小響應(即 1x1 像素),而沒有任何類型的 TLS 會話重用或 HTTP 保持活動。

引用自:https://serverfault.com/questions/754434