我有一個運行的應用程式: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 的核心,並受到虛擬鄰居的影響。
例如,t2.small 執行個體以每小時 12 個 CPU 積分的速率連續接收積分。此功能提供相當於 CPU 核心 20% 的基準效能。
還有另一個紙來自 nginx 本身:
結果摘要 使用現代加密演算法,單一虛擬化英特爾核心通常每秒可以執行多達 350 次完整的 2048 位元 SSL 握手操作。這相當於每個核心每秒有數百個新用戶使用您的服務。