時間:2020-09-03來源:www.farandoo.com作者:電腦系統城
ginx Ingress Controller 基于 Nginx 實現了 Kubernetes Ingress API,Nginx 是公認的高性能網關,但如果不對其進行一些參數調優,就不能充分發揮出高性能的優勢。之前我們在 Nginx Ingress on TKE 部署最佳實踐 一文中講了 Nginx Ingress 在 TKE 上部署最佳實踐,涉及的部署 YAML 其實已經包含了一些性能方面的參數優化,只是沒有提及,本文將繼續展開介紹針對 Nginx Ingress 的一些全局配置與內核參數調優的建議,可用于支撐我們的高并發業務。
我們先看下如何對 Nginx Ingress 進行內核參數調優,設置內核參數的方法可以用 initContainers 的方式,后面會有示例。
進程監聽的 socket 的連接隊列最大的大小受限于內核參數 net.core.somaxconn
,在高并發環境下,如果隊列過小,可能導致隊列溢出,使得連接部分連接無法建立。要調大 Nginx Ingress 的連接隊列,只需要調整 somaxconn 內核參數的值即可,但我想跟你分享下這背后的相關原理。
進程調用 listen 系統調用來監聽端口的時候,還會傳入一個 backlog 的參數,這個參數決定 socket 的連接隊列大小,其值不得大于 somaxconn 的取值。Go 程序標準庫在 listen 時,默認直接讀取 somaxconn 作為隊列大小,但 Nginx 監聽 socket 時沒有讀取 somaxconn,而是有自己單獨的參數配置。在 nginx.conf
中 listen 端口的位置,還有個叫 backlog 參數可以設置,它會決定 nginx listen 的端口的連接隊列大小。
server {
listen 80 backlog=1024;
...
如果不設置,backlog 在 linux 上默認為 511:
backlog=number
sets the backlog parameter in the listen() call that limits the maximum length for the queue of pending connections. By default, backlog is set to -1 on FreeBSD, DragonFly BSD, and macOS, and to 511 on other platforms.
也就是說,即便你的 somaxconn 配的很高,nginx 所監聽端口的連接隊列最大卻也只有 511,高并發場景下可能導致連接隊列溢出。
不過這個在 Nginx Ingress 這里情況又不太一樣,因為 Nginx Ingress Controller 會自動讀取 somaxconn 的值作為 backlog 參數寫到生成的 nginx.conf 中: https://github.com/kubernetes/ingress-nginx/blob/controller-v0.34.1/internal/ingress/controller/nginx.go#L592
也就是說,Nginx Ingress 的連接隊列大小只取決于 somaxconn 的大小,這個值在 TKE 默認為 4096,建議給 Nginx Ingress 設為 65535: sysctl -w net.core.somaxconn=65535
。
高并發場景會導致 Nginx Ingress 使用大量源端口與 upstream 建立連接,源端口范圍從 net.ipv4.ip_local_port_range
這個內核參數中定義的區間隨機選取,在高并發環境下,端口范圍小容易導致源端口耗盡,使得部分連接異常。TKE 環境創建的 Pod 源端口范圍默認是 32768-60999,建議將其擴大,調整為 1024-65535: sysctl -w net.ipv4.ip_local_port_range="1024 65535"
。
如果短連接并發量較高,它所在 netns 中 TIME_WAIT 狀態的連接就比較多,而 TIME_WAIT 連接默認要等 2MSL 時長才釋放,長時間占用源端口,當這種狀態連接數量累積到超過一定量之后可能會導致無法新建連接。
所以建議給 Nginx Ingress 開啟 TIME_WAIT 重用,即允許將 TIME_WAIT 連接重新用于新的 TCP 連接: sysctl -w net.ipv4.tcp_tw_reuse=1
Nginx 作為反向代理,對于每個請求,它會與 client 和 upstream server 分別建立一個連接,即占據兩個文件句柄,所以理論上來說 Nginx 能同時處理的連接數最多是系統最大文件句柄數限制的一半。
系統最大文件句柄數由 fs.file-max
這個內核參數來控制,TKE 默認值為 838860,建議調大: sysctl -w fs.file-max=1048576
。
給 Nginx Ingress Controller 的 Pod 添加 initContainers 來設置內核參數:
initContainers:
- name: setsysctl
image: busybox
securityContext:
privileged: true
command:
- sh
- -c
- |
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w fs.file-max=1048576
除了內核參數需要調優,Nginx 本身的一些配置也需要進行調優,下面我們來詳細看下。
Nginx 針對 client 和 upstream 的 keepalive 連接,均有 keepalive_requests 這個參數來控制單個 keepalive 連接的最大請求數,且默認值均為 100。當一個 keepalive 連接中請求次數超過這個值時,就會斷開并重新建立連接。
如果是內網 Ingress,單個 client 的 QPS 可能較大,比如達到 10000 QPS,Nginx 就可能頻繁斷開跟 client 建立的 keepalive 連接,然后就會產生大量 TIME_WAIT 狀態連接。我們應該盡量避免產生大量 TIME_WAIT 連接,所以,建議這種高并發場景應該增大 Nginx 與 client 的 keepalive 連接的最大請求數量,在 Nginx Ingress 的配置對應 keep-alive-requests
,可以設置為 10000,參考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#keep-alive-requests
同樣的,Nginx 與 upstream 的 keepalive 連接的請求數量的配置是 upstream-keepalive-requests
,參考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#upstream-keepalive-requests
但是,一般情況應該不必配此參數,如果將其調高,可能導致負載不均,因為 Nginx 與 upstream 保持的 keepalive 連接過久,導致連接發生調度的次數就少了,連接就過于 "固化",使得流量的負載不均衡。
Nginx 針對 upstream 有個叫 keepalive 的配置,它不是 keepalive 超時時間,也不是 keepalive 最大連接數,而是 keepalive 最大空閑連接數。
它的默認值為 32,在高并發下場景下會產生大量請求和連接,而現實世界中請求并不是完全均勻的,有些建立的連接可能會短暫空閑,而空閑連接數多了之后關閉空閑連接,就可能導致 Nginx 與 upstream 頻繁斷連和建連,引發 TIME_WAIT 飆升。在高并發場景下可以調到 1000,參考:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#upstream-keepalive-connections
max-worker-connections
控制每個 worker 進程可以打開的最大連接數,TKE 環境默認 16384,在高并發環境建議調高,比如設置到 65536,這樣可以讓 nginx 擁有處理更多連接的能力,參考:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#max-worker-connections
Nginx 全局配置通過 configmap 配置(Nginx Ingress Controller 會 watch 并自動 reload 配置):
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-ingress-controller
# nginx ingress 性能優化: https://www.nginx.com/blog/tuning-nginx/
data:
# nginx 與 client 保持的一個長連接能處理的請求數量,默認 100,高并發場景建議調高。
# 參考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#keep-alive-requests
keep-alive-requests: "10000"
# nginx 與 upstream 保持長連接的最大空閑連接數 (不是最大連接數),默認 32,在高并發下場景下調大,避免頻繁建聯導致 TIME_WAIT 飆升。
# 參考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#upstream-keepalive-connections
upstream-keepalive-connections: "200"
# 每個 worker 進程可以打開的最大連接數,默認 16384。
# 參考: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#max-worker-connections
max-worker-connections: "65536"
本文分享了對 Nginx Ingress 進行性能調優的方法及其原理的解釋,包括內核參數與 Nginx 本身的配置調優,更好的適配高并發的業務場景,希望對大家有所幫助。
2022-04-13
蘋果系統安裝雙系統圖文教程 蘋果系統怎么裝雙系統 ?2022-04-13
遠程登錄Linux CentOS系統方法 怎么遠程登錄Linux CentOS系統?2022-03-21
CentOS7安裝MYSQL8.X的詳解教程很多網友對于linux系統比較陌生,更別說linux系統安裝了。有使用筆記本電腦的網友需要用到linux系統,不過卻不知道怎么安裝,所以下面小編要來跟大家說說linux操作系統安裝步驟詳細,大家一起來看看吧。...
2022-03-07
RedFlag紅旗Linux系統怎么安裝?電腦想要安裝雙系統,該怎么安裝RedFlag紅旗系統呢?下面我們就來看看紅旗Red Flag安裝全程圖解,詳細請看下文介紹...
2022-01-23