Nginx服務器連接數(shù)告警處理及解決方案
序言
在系統(tǒng)間交互頻繁的場景中,連接數(shù)是一個重要的指標。通常,我們會為連接數(shù)設置一個告警閾值,比如幾萬。
當連接數(shù)超過這個閾值時,就會觸發(fā)告警。連接數(shù)過多會消耗CPU、內(nèi)存、文件句柄等資源。雖然可以通過提高閾值(如10萬或30萬)來暫時緩解告警問題,但只要CPU和內(nèi)存資源未告警,情況還不算緊急。本文將詳細介紹如何處理Nginx服務器連接數(shù)告警問題。
服務端連接數(shù)異常告警排查
1. 查看連接狀態(tài)
當Nginx充當轉(zhuǎn)發(fā)服務器時,連接數(shù)告警是很常見的,尤其是在QPS(每秒查詢數(shù))很高的情況下。收到告警后,我們通常需要登錄服務器,使用netstat或ss命令來查看連接狀態(tài)。
注意:在使用ss命令時,如果命令格式和netstat類似,默認情況下ss不會顯示TIME-WAIT狀態(tài)的連接,因為ss認為這種狀態(tài)不重要。
執(zhí)行以下命令查看連接狀態(tài):
netstat -an | grep ESTABLISHED # 或者 ss -ant | grep ESTABLISHED
執(zhí)行命令后,我們可以發(fā)現(xiàn)哪種狀態(tài)的連接占用最多。在正常情況下,TIME-WAIT狀態(tài)的連接可能占用很多。接下來,我們可以查看是哪些IP占用了大量連接。
在當前場景下,如果發(fā)現(xiàn)與后端服務連接的TIME-WAIT狀態(tài)較多,即顯示的都是Nginx的upstream服務器,那么可以大致判斷為Nginx與upstream的連接是短連接,未開啟長連接配置。
2. 查看Nginx的配置
在默認情況下,如果在upstream的配置中沒有特別設置,Nginx與upstream的連接是短連接的。
特別需要注意的是keepalive參數(shù),它限制的是空閑連接的數(shù)量(不會限制upstream的最大連接數(shù))。以下是相關參數(shù)的配置:
Syntax: keepalive_timeout timeout; Default: keepalive_timeout 60s; Context: upstream Syntax: keepalive_requests number; Default: keepalive_requests 1000; Context: upstream
在一般情況下,這兩個參數(shù)保持默認值即可。如果并發(fā)量很大,可以將keepalive設置為300,并將timeout和requests設置得大一點,以減少連接被釋放的次數(shù)。
如果keepalive_timeout設置得很小,會導致連接不停地被釋放和創(chuàng)建,最直接的影響是增大請求的響應時間(RT),消耗Nginx的資源,并有更高的連接和關閉開銷,同時也會影響后端服務器的性能。
在upstream的長連接需要關閉時,會按照四次揮手協(xié)議進行關閉,并且會等連接處理完成后再關閉,不會像某些框架那樣到了時間直接關閉,不管請求是否結(jié)束。
3. 客戶端的長連接
對于Nginx來說,默認情況下就開啟了客戶端的長連接功能,所以一般只需要配置超時時間即可。
Syntax: keepalive_timeout timeout [header_timeout]; Default: keepalive_timeout 75s; Context: http, server, location
需要注意的是,如果客戶端的連接都是短連接,而沒有長連接,那么需要檢查客戶端的請求頭,查看Connection頭部是否為close,強制要求使用短連接。
另外,還需要查看客戶端使用的協(xié)議是否是HTTP/1.0(默認都是短連接)。如果未出現(xiàn)上述情況,那么需要檢查Nginx的配置中,是否將Connection頭部設置為空字符串,否則不但客戶端是短連接,還會影響Nginx和upstream之間也是短連接。
如果客戶端發(fā)送的Connection頭部是close,但是Nginx設置了Connection頭部為空字符串,那么Nginx和后端依舊是長連接。
4. 優(yōu)化操作系統(tǒng)的內(nèi)核參數(shù)
如果發(fā)現(xiàn)客戶端的連接有很多TIME-WAIT狀態(tài),可以通過優(yōu)化操作系統(tǒng)的內(nèi)核參數(shù)來解決。編輯/etc/sysctl.conf文件,添加或修改以下參數(shù):
net.ipv4.tcp_keepalive_time = 1200 # 使用TCP探測盡快處理空閑的連接 net.ipv4.tcp_fin_timeout = 30 # 設置FIN WAIT2等待時間,減少等待關閉連接的時間,盡快釋放系統(tǒng)資源 net.ipv4.tcp_max_tw_buckets = 200000 # 控制TIMEWAIT數(shù)量 net.ipv4.tcp_tw_recycle = 0 # 禁用TIMEWAIT的快速回收,已廢棄,防止?jié)撛诰W(wǎng)絡問題 net.ipv4.tcp_tw_reuse = 1 # 啟用TIMEWAIT狀態(tài)的連接便于新的連接 net.ipv4.tcp_timestamps = 1 # 啟用TCP時間戳選項,提高網(wǎng)絡傳輸效率,提高TCP連接安全性 net.ipv4.netdev_max_backlog = 262148 # 允許入隊列的數(shù)據(jù)包的最大數(shù)量
保存文件后,執(zhí)行sysctl -p命令使配置生效。
運行結(jié)果示例
假設我們在服務器上執(zhí)行了以下命令來查看連接狀態(tài):
ss -ant | grep ESTABLISHED
可能得到如下輸出:
ESTAB 0 0 192.168.1.100:80 192.168.1.101:54321 ESTAB 0 0 192.168.1.100:80 192.168.1.102:54322 ...
這表示有多個建立的連接。通過類似的方法,我們可以進一步分析具體哪些IP或端口占用了大量連接。
總結(jié)
Nginx的復雜之處在于它既是客戶端又是服務端。在充當客戶端時,需要設置連接超時參數(shù);在充當服務端時,也需要設置連接超時參數(shù)。并且這些參數(shù)的名字還差不多,只是寫的位置不一樣,有的是在http段中,有的是在upstream段中。通過仔細排查和優(yōu)化配置,我們可以有效解決Nginx服務器連接數(shù)告警問題。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Nginx?map?實現(xiàn)時間格式轉(zhuǎn)換的方法
最近我們需要把?Nginx?的日志接入到自研的日志采集平臺上,但是這個平臺只支持?JSON?格式,所以需要把?Nginx?日志格式改成?JSON?格式,這篇文章主要介紹了Nginx?map?實現(xiàn)時間格式轉(zhuǎn)換,需要的朋友可以參考下2023-09-09
nginx proxy_set_header設置自定義header的實現(xiàn)步驟
在Nginx中,使用?proxy_set_header指令可以自定義header并在反向代理時傳遞到后端服務器,本文就來詳細的介紹一下,具有一定的參考價值,感興趣的可以了解一下2024-05-05

