問題描述
Nginx 需要注意一些設定值來調教,優化對高併發的處理能力。
解決方法
- backlog 參數決定 socket queue 的大小,預設為 511,參照內核參數調整,最高為 65535。
1
2
3
4server {
listen 80 backlog=4096;
...
} - 關於全列隊與半列隊的設定,可以參考以下設定,預設為全列隊。全列隊長度的計算方式為 min(backlog, somaxconn),半列隊則是 min(backlog, somaxconn, tcp_max_syn_backlog)
1
2
3
4
5
6
7
8server {
listen 80;
# 全列隊
accept_mutex on;
# 半列隊
accept_mutex off;
...
} - net.core.somaxconn 是內核參數,決定全列隊的大小,預設為 128,可以調整為 65535。 net.core.tcp_max_syn_backlog 是內核參數,決定半列隊的大小,預設為 1024,可以調整為 65535。
1
2
3
4
5
6$ sysctl -w net.core.somaxconn=65535
$ sysctl -w net.core.tcp_max_syn_backlog=65535
# 永久生效
$ echo "net.core.somaxconn=65535" >> /etc/sysctl.conf
$ echo "net.core.tcp_max_syn_backlog=65535" >> /etc/sysctl.conf
$ sysctl -p
參考資料
- SYNC Cookie 時,net.ipv4.tcp_syncookies = 1,可以防止 SYN Flood 攻擊。但此時 tcp_max_syn_backlog 會被忽略,因為 SYN Cookie 會將 SYN 放在 Cookie 中,所以不會佔用半列隊的空間。
- 全列隊與半列隊的差異,全列隊是一個全局的列隊,半列隊是每個 listen socket 有一個列隊。用途上,全列隊適合高併發,半列隊適合低併發。例如,全列隊適合網站,半列隊適合 API 服務。