nginx引數調優能提升多少效能

2023-11-02 21:00:56

前言

nginx安裝後一般都會進行引數優化,網上找找也有很多相關文章,但是這些引數優化對Nginx效能會有多大影響?為此我做個簡單的實驗測試下這些引數能提升多少效能。

宣告一下,測試流程比較簡單,後端服務也很簡單,測試時間也很短,所以實驗並不嚴謹,結果僅作參考,需要根據實際情況進行引數調優。

文章或有錯誤和疏漏之處,歡迎各位大佬指出或補充。

環境

IP 作業系統 CPU 記憶體 部署服務
192.168.3.60 Debian 11.8 4 4 GB wrk
192.168.3.61 Debian 11.8 4 4 GB nginx
192.168.3.62 Debian 11.8 4 4 GB 後端服務
  • nginx:版本1.24.0,編譯引數:
./configure --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_gunzip_module --with-http_gzip_static_module --with-stream --with-compat --with-pcre-jit --prefix=/home/admin/apps/nginx
  • 使用wrk進行效能測試,版本為 4.1.0,通過 apt 包管理器安裝。
  • 因為主要測試nginx反向代理的效能,所以用go寫了個響應"hello world"的api,減少後端服務導致的效能影響。

測試方法:調整nginx引數後多次執行wrk,取平均值。(方法並不嚴謹,應該用更專業的工具測試執行幾小時,將測試資料採用更科學的方法彙總,但時間精力有限,所以採用這個非常簡單無腦的實驗方法)

實驗結果

下面的實驗過程主要就是調引數,比較繁瑣,所以把實驗結果先放到前面。綜合設定可參考「實驗過程 - 13. 綜合調優」。

再次宣告,由於測試流程和後端邏輯都比較簡單,伺服器和網路情況也沒嚴格控制變數所以結果僅供參考。

根據實驗結果來看,增大工作程序數能直接提升效能,但不是和CPU核心數一致就能最大化,可能少一點才能達到最佳效能。

除了nginx和系統引數調優,網路和後端服務對效能的影響也很大,而且在大部分ToB業務場景下,後端服務和資料庫才是效能短板。

序號 測試方式 Nginx引數優化項 總請求數 平均每秒請求數 平均延遲 優化效果
1 wrk -> 後端 4139984 68884.59 1.66ms +673%
2 wrk -> nginx -> 後端 無,預設設定 534859 8911.30 12.04ms -
3.1 wrk -> nginx -> 後端 設定工作程序數為2 1027745 17127.49 5.95ms +92.19%
3.2 wrk -> nginx -> 後端 設定工作程序數為3 676651 11274.05 8.97ms +26.51%
3.3 wrk -> nginx -> 後端 設定工作程序數為auto(4) 547794 9125.66 11.14ms +2.41%
4 wrk -> nginx -> 後端 設定工作程序數和CPU親和性為auto 537713 8958.10 11.67ms +0.52%
5 wrk -> nginx -> 後端 在4的基礎上設定worker_connections 65535; 532758 8874.85 11.80ms -0.4%
6 wrk -> nginx -> 後端 在5的基礎上設定accept_mutex on; 425540 7088.39 15.58ms -20.45%
7 wrk -> nginx -> 後端 在6的基礎上設定multi_accept on 591500 9854.77 10.60ms +10.58%
8 wrk -> nginx -> 後端 在7的基礎上設定改為upstream 558679 9308.30 12.00ms +4.45%
9 wrk -> nginx -> 後端 在8的基礎上設定keepalive 632673 10541.49 10.06ms +18.29%
10 wrk -> nginx -> 後端 在9的基礎上設定加一個後端 1006485 16772.08 6.53ms +88.21%
11 wrk -> nginx -> 後端 在2的基礎上設定加一個後端 610882 10178.26 10.21ms +14.21%
12 wrk -> nginx -> 後端 在3.1的基礎上設定keepalive 1041024 17348.36 5.94ms +94.67%
13 wrk -> nginx -> 後端 在2的基礎上設定deferred 596197 9934.61 10.90ms +11.48%
14 wrk -> nginx -> 後端 在2的基礎上修改核心引數 581535 9689.91 10.95ms +8.73%
15 wrk -> nginx -> 後端 綜合調優 1087151 18115.78 5.94ms +103.28%

單獨測試nginx的效能,避免後端服務和網路情況的影響。

序號 Nginx引數優化項 總請求數 平均每秒請求數 平均延遲 優化效果
1 無,預設設定 2327400 38787.61 2.71ms -
2 在1的基礎上設定工作程序數為auto 7418729 123633.13 791.04us 218.74%
3 在2的基礎上設定CPU親和性 7437087 123945.45 784.02us 219.54%
4 在3的基礎上設定工作程序連線數和多請求 7638947 127300.44 764.67us 228.19%

調整環境,nginx都採用預設設定,只是修改了各元件的位置。因為元件在同一臺伺服器,資源競爭情況也會影響效能。

環境 總請求數 平均每秒請求數 平均延遲
wrk、nginx和後端各在不同的伺服器 534859 8911.30 12.04ms
wrk單獨伺服器,nginx和後端在同一臺伺服器 386630 6441.05 16.24ms
wrk、nginx和後端在同一臺伺服器 402163 6700.38 15.15ms

實驗過程

1. 直連後端測試

首先用wrk直接測試後端。因為沒有中間商賺差價,所以理論上直連效能會比nginx代理的效能高。

# curl 測試後端響應是否正常
curl http://192.168.3.62:8101

# wrk 直接測試後端服務。執行緒數為4,連線數為100,測試時間為60秒。
wrk -t4 -c100 -d60s http://192.168.3.62:8101

wrk測試結果

總請求數 平均每秒請求數 平均延遲
4139984 68884.59 1.66ms

2. 使用nginx預設設定代理

nginx剛安裝後有一個預設設定,這裡只改了location /的設定,修改為反向代理到後端服務

location / {
    #root   html;
    #index  index.html index.htm;
    proxy_pass http://192.168.3.62:8101;
}

wrk測試結果。相較於後端直連,效能縮水很多

總請求數 平均每秒請求數 平均延遲
534859 8911.30 12.04ms

3. 增加工作程序數

nginx預設工作程序數為1,通過修改worker_processes可指定,一般小於或等於CPU核心數

worker_processes 總請求數 平均每秒請求數 平均延遲 對比預設設定
1(預設) 534859 8911.30 12.04ms -
2 1027745 17127.49 5.95ms +92.19%
3 676651 11274.05 8.97ms +26.51%
auto(4) 547794 9125.66 11.14ms +2.41%

4. 設定CPU親和性

通過worker_cpu_affinity繫結工作程序和CPU,避免nginx程序在CPU之間切換導致的偽共用帶來的效能問題。

nginx設定:

worker_processes  auto;
worker_cpu_affinity auto;

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
537713 8958.10 11.67ms +0.52%

5. 設定worker_connections

worker_connections用於設定每個Nginx程序可處理並行連線的最大數,預設為1024。

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
}

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
532758 8874.85 11.80ms -0.4%

6. 啟用互斥鎖

nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	accept_mutex on;
}

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
425540 7088.39 15.58ms -20.45%

7. 啟用多請求支援

預設情況下,每個工作程序一次只接受一個新連線。開啟後,每個工作程序將接受所有的新連線。

nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	accept_mutex on;
	multi_accept on;
}

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
591500 9854.77 10.60ms +10.58%

8. 使用upstream

之前的設定都通過proxy_pass直接反向代理到後端,修改為upstream。

nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	accept_mutex on;
	multi_accept on;
}
http {
	upstream backend {
		server 192.168.3.62:8101;
	}
	server {
        location / {
            proxy_pass http://backend;
        }
	}
}

wrk測試結果。效能有所降低,但在多個後端的情況下,還是設定upstream更方便。

總請求數 平均每秒請求數 平均延遲 對比預設設定
558679 9308.30 12.00ms +4.45%

9. 設定keepalive長連線

長連線的存在可以減少建立和關閉TCP連線帶來的消耗和延遲。

nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	accept_mutex on;
	multi_accept on;
}
http {
	upstream backend {
		server 192.168.3.62:8101;
		keepalive 32;
		keepalive_requests 2000;
	}
	server {
        location / {
            proxy_pass http://backend;
        }
	}
}

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
632673 10541.49 10.06ms +18.29%

10. 增加後端範例數

分別在預設設定和上一步的基礎上,將後端範例數加1。

修改後的nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	accept_mutex on;
	multi_accept on;
}
http {
	upstream backend {
		server 192.168.3.62:8101;
		server 192.168.3.62:8102;
		keepalive 32;
		keepalive_requests 2000;
	}
	server {
        location / {
            proxy_pass http://backend;
        }
	}
}

wrk測試結果

設定 總請求數 平均每秒請求數 平均延遲 對比預設設定
預設設定多後端 610882 10178.26 10.21ms +14.21%
預設設定,長連線,工作程序數2 1041024 17348.36 5.94ms +94.67%
修改設定多後端 1006485 16772.08 6.53ms +88.21%

11. 延遲處理新連線

設定deferred引數可延遲處理新連線,加上這個設定後,當用戶與nginx伺服器建立連線時,只有使用者有請求資料時才會將TCP連線狀態改為ESTABLISHED,否則就直接丟棄這條連線。通過減少伺服器和使用者端之間發生的三次握手建立連線的數量來幫助提高效能。

nginx設定

worker_processes  1;
events {
	worker_connections 1024;
}
http {
	server {
        listen 8100 deferred;
	}
}

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
596197 9934.61 10.90ms +11.48%

12. 修改核心引數

修改的核心引數如下

# 網路卡接受封包的佇列最大長度
net.core.netdev_max_backlog = 24800
# 已經收到syn包,但是還沒有來得及確認的連線佇列
net.ipv4.tcp_max_syn_backlog = 24800
# 埠監聽佇列的最大長度, 存放的是已經處於ESTABLISHED而沒有被應用程式接管的TCP連線
net.core.somaxconn = 65535
# SYN的超時重傳次數
net.ipv4.tcp_syn_retries = 2
# 伺服器端等待使用者端響應ACK的超時重傳次數
net.ipv4.tcp_synack_retries = 2
# 作為伺服器端才擁有TCP Fast Open機制
net.ipv4.tcp_fastopen = 2

nginx的設定為預設設定。

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
581535 9689.91 10.95ms +8.73%

13. 綜合調優

開啟多請求支援,增加工作程序連線數,設定長連線,增加後端範例,修改核心引數。

如果不想一遍遍修改工作程序數,直接設定為auto最省事,雖然不一定會是最優設定,但總比預設強。

nginx設定

worker_processes  auto;
events {
	worker_connections 65535;
	multi_accept on;
}
http {
	upstream backend {
		server 192.168.3.62:8101;
		server 192.168.3.62:8102;
		keepalive 32;
		keepalive_requests 2000;
	}
	server {
		lister deferred backlog=24800;
        location / {
            proxy_pass http://backend;
        }
	}
}

核心引數

net.core.netdev_max_backlog = 24800
net.ipv4.tcp_max_syn_backlog = 24800
net.core.somaxconn = 65535
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_fastopen = 2

wrk測試結果

總請求數 平均每秒請求數 平均延遲 對比預設設定
1087151 18115.78 5.94ms +103.28%

14. 單獨測試nginx

以上測試場景都有nginx反向代理後端,而網路和後端也會在一定程度上影響nginx效能,所以這裡單獨測試nginx。

nginx設定

worker_processes  auto;
worker_cpu_affinity auto;
events {
	worker_connections 65535;
	multi_accept on;
}
http {
	server {
        location / {
            return 200 'hello world';
        }
	}
}

wrk測試結果。在沒有反向代理的情況下,增加工作程序數就能直接提升nginx效能。

序號 Nginx引數優化項 總請求數 平均每秒請求數 平均延遲 優化效果
1 無,預設設定 2327400 38787.61 2.71ms -
2 在1的基礎上設定工作程序數為auto 7418729 123633.13 791.04us 218.74%
3 在2的基礎上設定CPU親和性 7437087 123945.45 784.02us 219.54%
4 在3的基礎上設定工作程序連線數和多請求 7638947 127300.44 764.67us 228.19%