NGINX HTTPS 反向代理 - 快速 TTFB 但並發性低

NGINX HTTPS 反向代理 - 快速 TTFB 但並發性低

我有一個運行的應用程式:NGINX (SSL) => VARNISH (CACHE) => APACHE/PHP。

跑步ab基準,我能夠透過 EC2 t2.small 執行個體在 varnish 層(透過 HTTP)上實現 30k+ 請求/秒。然而,當我透過 NGINX (HTTPS) 執行測試時,我每秒只能推送 160 個請求(來自公共網路的 TTFB 平均為 43 毫秒)。

@nginx.conf

user  nginx;
worker_processes  auto;

worker_rlimit_nofile 65535;

error_log  /var/log/nginx/error.log;

pid        /var/run/nginx.pid;


events {
    worker_connections  16024;
        multi_accept on;
}

在 http 級別:

sendfile        on;
tcp_nopush     on;

keepalive_timeout  10;


ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

@域.conf

server {
        listen 443 ssl;

        server_name xyz.com;
        ssl_certificate /home/st/ssl3/xyz.crt;
        ssl_certificate_key /home/xyz/ssl3/xyz.key;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

        ssl_session_tickets on;

        location / {

                proxy_buffers 8 8k;
                proxy_buffer_size 2k;


            proxy_pass http://127.0.0.1:79;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Port 443;
            proxy_set_header Host $host;

                proxy_redirect off;

        }

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}

這是 Apache 的直接基準測試

內部=>@APACHE:

Concurrency Level:      10
Time taken for tests:   0.694 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1002
Keep-Alive requests:    996
Total transferred:      705122 bytes
HTML transferred:       401802 bytes
Requests per second:    1440.93 [#/sec] (mean)
Time per request:       6.940 [ms] (mean)
Time per request:       0.694 [ms] (mean, across all concurrent requests)
Transfer rate: 992.22 [Kbytes/sec] received

這是 Varnish 的基準(它之前以 20-30k 的速度運行 - 用盡了我的 CPU 週期,平均 ATM 為 4-8k rps)

內部 => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   0.232 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    0
Total transferred:      23439800 bytes
HTML transferred:       23039412 bytes
Requests per second:    4310.16 [#/sec] (mean)
Time per request:       2.320 [ms] (mean)
Time per request:       0.232 [ms] (mean, across all concurrent requests)
Transfer rate:          98661.39 [Kbytes/sec] received

這是 NGINX 的基準測試HTTP協定

內 => @NGINX[HTTP] => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   0.082 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1001
Keep-Alive requests:    1000
Total transferred:      382382 bytes
HTML transferred:       184184 bytes
Requests per second:    12137.98 [#/sec] (mean)
Time per request:       0.824 [ms] (mean)
Time per request:       0.082 [ms] (mean, across all concurrent requests)
Transfer rate:          4532.57 [Kbytes/sec] received

這是 NGINX 的基準測試HTTPS

內部 => @NGINX[HTTPS=>HTTP] => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   7.029 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1000
Keep-Alive requests:    0
Total transferred:      663000 bytes
HTML transferred:       401000 bytes
Requests per second:    142.27 [#/sec] (mean)
Time per request:       70.288 [ms] (mean)
Time per request:       7.029 [ms] (mean, across all concurrent requests)
Transfer rate:          92.12 [Kbytes/sec] received

答案1

根據您提供(和未提供)的信息,我只能猜測。但從實例類型(t2 具有基於票據的突發性能,當票據用完時,獲得大約 20% 的核心;這不是一個進行基準測試的好實例)和ab測試的使用(順便說一句,當你編寫它時)來判斷說到“AB測試”,首先想到的是)我想說你的表現幾乎符合預期。

當啟動 SSL 或 TLS 會話時,效能最密集的任務不是資料加密/解密,而是金鑰交換。由於ab不使用 SSL 會話緩存,因此必須在每個連線上進行金鑰交換。

根據實際使用的 cipher/kex/auth 套件(無法判斷,沒有ab提供輸出),這對 CPU 來說可能是相當多的工作。由於兩端都在同一台機器上,因此每個連接的 CPU 要求加倍(這是一個簡化,但在這裡已經足夠好了)。

在現實世界中,keep alives 可能會幫助你獲得更好的效能(取決於客戶端,普通瀏覽器使用它;嘗試一下ab -k)。並且您將從您提到的 SSL 會話快取中獲得更好的效能(同樣取決於客戶端,普通瀏覽器支援它)。

還有其他幾種方法可以幫助您提高績效。當然你可以獲得更好的硬體。您可以最佳化金鑰大小(取決於應用程式所需的保護等級) - 較小的金鑰通常使用起來更便宜。從不同的機器進行測試可能會也可能不會改善明顯的性能。獲得不同的 OpenSSL 版本或不同的 SSL 庫也可以提供更好的效能。

僅供參考,你可以看看這張紙由英特爾。他們確實比較了高度優化的機器(和一些優化的軟體)上的性能。假設您的可用運算能力不到他們的 1/30(如果您沒有票,則可能低至 1/150)。

不過,如果您需要高效能 SSL,則可能值得考慮使用 Amazon ELB 為您執行 SSL 終止,因為您已經在 EC2 上。

編輯:例如阿帕奇JMeter使用 ssl 上下文快取。httperf也是如此。我發現 JMeter 特別擅長模擬現實生活中的負荷。但對於這種 httperf 會話快取方式來說效果最好。

沒有看到任何區別-k可能是因為它還沒有被使用。取決於並發設定(至少在我的機器上),它似乎也取決於 url。如果我使用的網域指向 url 中的多個 IP,則它不會使用 keepalive(不要問我為什麼)。

取決於您對大規模的看法,但我不希望在這個相當小的實例上每秒突發超過大約 500 個連接,並且持續不超過 250 cps。

將 varnish 純文字 http 與 nginx ssl 進行比較就像將梨子與蘋果進行比較。或者更確切地說,就硬體需求而言,將藍莓與西瓜進行比較。

再次供您參考(注意這Keep-Alive requests: 100條線)。

沒有-k

Concurrency Level:      1
Time taken for tests:   0.431 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      399300 bytes
HTML transferred:       381200 bytes
Requests per second:    232.26 [#/sec] (mean)
Time per request:       4.305 [ms] (mean)
Time per request:       4.305 [ms] (mean, across all concurrent requests)
Transfer rate:          905.69 [Kbytes/sec] received

-k

Concurrency Level:      1
Time taken for tests:   0.131 seconds
Complete requests:      100
Failed requests:        0
Keep-Alive requests:    100
Total transferred:      402892 bytes
HTML transferred:       381200 bytes
Requests per second:    762.11 [#/sec] (mean)
Time per request:       1.312 [ms] (mean)
Time per request:       1.312 [ms] (mean, across all concurrent requests)
Transfer rate:          2998.53 [Kbytes/sec] received

Edit2:嗯,你需要明白,直接從記憶體中提供內容(這就是 Varnish 正在做的事情)是非常簡單的。您解析標頭,在記憶體中找到內容,然後將其吐出。 Varnish 在這方面表現出色。

建立加密連線是完全不同的等級。因此,一旦新增 nginx,它就必須進行 SSL 握手(金鑰交換、驗證)和加密,這需要更多資源。然後它解析標頭。然後它必須建立另一個到 Varnish 的 TCP 連線。

再次,在前面提到的英特爾論文,他們有 28 個核心,並對 OpenSSL 進行了一些調整,以實現 38k HTTPS cps(比您的 Varnish 效能多一點)。您擁有大約 1/5 的核心,並受到虛擬鄰居的影響。

引用Amazon EC2 執行個體列表

例如,t2.small 執行個體以每小時 12 個 CPU 積分的速率連續接收積分。此功能提供相當於 CPU 核心 20% 的基準效能。

還有另一個來自 nginx 本身:

結果摘要 使用現代加密演算法,單一虛擬化英特爾核心通常每秒可以執行多達 350 次完整的 2048 位元 SSL 握手操作。這相當於每個核心每秒有數百個新用戶使用您的服務。

相關內容