面對nginx服務(wù)拒絕連接問題,應(yīng)立即采取措施恢復(fù)服務(wù)并減少損失。1.檢查服務(wù)器資源是否打滿;2.臨時(shí)擴(kuò)容,云服務(wù)器可升配,物理機(jī)可加實(shí)例配合負(fù)載均衡;3.嘗試平滑重啟nginx;4.啟用限流功能控制流量;5.排查日志、系統(tǒng)及網(wǎng)絡(luò)狀態(tài);6.優(yōu)化配置如調(diào)整worker進(jìn)程數(shù)與連接數(shù)、keepalive超時(shí)時(shí)間等;7.結(jié)合監(jiān)控、壓力測試與容量規(guī)劃做好預(yù)防;8.通過分析流量來源、請求類型、頻率及user-agent判斷是否為惡意攻擊;9.調(diào)整worker進(jìn)程數(shù)和連接數(shù)能提升并發(fā)處理能力,但需結(jié)合硬件與業(yè)務(wù)合理設(shè)置;10.還需排查后端服務(wù)、網(wǎng)絡(luò)、防火墻、系統(tǒng)資源及代碼問題,全面定位原因。
面對突發(fā)流量,Nginx服務(wù)拒絕連接,最直接的應(yīng)對就是盡快恢復(fù)服務(wù),減少損失。快速排查并臨時(shí)擴(kuò)容是關(guān)鍵,同時(shí)要記錄問題,以便后續(xù)優(yōu)化。
解決方案
-
快速止血:
- 檢查服務(wù)器資源: top、htop、free -m 命令走起,看看CPU、內(nèi)存、磁盤I/O是不是被打爆了。如果是,那就是資源瓶頸。
- 臨時(shí)擴(kuò)容: 如果是云服務(wù)器,直接升配!這是最快的。如果是物理機(jī),那就只能臨時(shí)增加 Nginx 實(shí)例,用負(fù)載均衡分?jǐn)偭髁浚ㄈ绻?a href="http://www.babyishan.com/tag/%e6%9e%b6%e6%9e%84">架構(gòu)支持)。
- 重啟 Nginx: 簡單粗暴,但有時(shí)候有效。nginx -s reload 或者 systemctl restart nginx。注意:reload 是平滑重啟,盡量用這個(gè),避免服務(wù)中斷。
- 限流: Nginx 本身可以做限流,比如限制單個(gè) IP 的連接數(shù)。但是要注意,誤殺正常用戶。
-
排查原因:
- Nginx 日志: /var/log/nginx/Error.log 和 /var/log/nginx/access.log 是重點(diǎn)。看看有沒有什么異常,比如 upstream 超時(shí)、連接數(shù)過多等等。
- 系統(tǒng)日志: /var/log/syslog 或者 /var/log/messages 看看有沒有系統(tǒng)層面的錯(cuò)誤。
- 網(wǎng)絡(luò)連接數(shù): netstat -an | grep :80 | wc -l 和 ss -ant | grep :80 | wc -l 查看當(dāng)前連接數(shù),是不是超過了 Nginx 的配置。
- TCP 連接狀態(tài): netstat -ant | awk ‘{print $NF}’ | sort | uniq -c | sort -n 看看是不是有大量的 TIME_WaiT 或者 CLOSE_WAIT 連接。
-
- 調(diào)整 Nginx worker 進(jìn)程數(shù): worker_processes auto; 根據(jù) CPU 核心數(shù)設(shè)置。
- 增加 worker 連接數(shù): worker_connections 65535; 但要確保系統(tǒng)內(nèi)核參數(shù)也允許這么高的連接數(shù)。
- 調(diào)整 keepalive 超時(shí)時(shí)間: keepalive_timeout 75s; 減少 TIME_WAIT 連接。
- 開啟 gzip 壓縮: gzip on; 減少帶寬消耗。
- 緩存靜態(tài)資源: 利用 Nginx 的緩存功能,減少后端服務(wù)器的壓力。
-
預(yù)防措施:
- 監(jiān)控: 完善的監(jiān)控系統(tǒng)是關(guān)鍵,提前發(fā)現(xiàn)問題。
- 壓力測試: 定期進(jìn)行壓力測試,模擬高并發(fā)場景,發(fā)現(xiàn)瓶頸。
- 容量規(guī)劃: 根據(jù)業(yè)務(wù)增長預(yù)測,提前做好容量規(guī)劃。
如何區(qū)分是惡意攻擊還是正常流量突增?
- 流量來源分析: 通過 Nginx 日志或者流量分析工具(比如 grafana + prometheus),看看流量是不是集中在某些 IP 地址或者地區(qū)。如果是,很可能是攻擊。
- 請求類型分析: 看看是不是有大量的 POST 請求,或者請求的 URL 都是一些不存在的頁面。
- 請求頻率分析: 如果單個(gè) IP 在短時(shí)間內(nèi)發(fā)送大量的請求,很可能是惡意行為。
- User-Agent 分析: 看看 User-Agent 是不是正常的瀏覽器,或者是一些爬蟲工具。
- 結(jié)合 WAF: Web 應(yīng)用防火墻 (WAF) 可以有效防御常見的 Web 攻擊,比如 sql 注入、xss 攻擊等等。
為什么調(diào)整 Nginx worker 進(jìn)程數(shù)和連接數(shù)可以緩解壓力?
Nginx 是基于事件驅(qū)動(dòng)的架構(gòu),worker 進(jìn)程負(fù)責(zé)處理客戶端的請求。
- worker 進(jìn)程數(shù): 增加 worker 進(jìn)程數(shù),可以充分利用多核 CPU 的性能,并發(fā)處理更多的請求。worker_processes auto; 會讓 Nginx 自動(dòng)根據(jù) CPU 核心數(shù)設(shè)置 worker 進(jìn)程數(shù)。
- worker 連接數(shù): 每個(gè) worker 進(jìn)程可以處理多個(gè)連接。增加 worker 連接數(shù),可以提高 Nginx 的并發(fā)能力。worker_connections 65535; 表示每個(gè) worker 進(jìn)程最多可以處理 65535 個(gè)連接。
但是,增加 worker 進(jìn)程數(shù)和連接數(shù)并不是越多越好。過多的 worker 進(jìn)程會增加系統(tǒng)開銷,過多的連接數(shù)可能會導(dǎo)致內(nèi)存不足。需要根據(jù)服務(wù)器的硬件配置和業(yè)務(wù)特點(diǎn)進(jìn)行調(diào)整。
除了 Nginx 配置,還有哪些因素可能導(dǎo)致服務(wù)拒絕連接?
- 后端服務(wù)器: 如果后端服務(wù)器(比如 tomcat、Node.JS)也出現(xiàn)了問題,Nginx 也會受到影響。
- 網(wǎng)絡(luò)問題: 網(wǎng)絡(luò)延遲、丟包等問題也會導(dǎo)致服務(wù)拒絕連接。
- 防火墻: 防火墻可能會阻止某些 IP 地址的訪問。
- 系統(tǒng)資源: CPU、內(nèi)存、磁盤 I/O 等資源不足也會導(dǎo)致服務(wù)拒絕連接。
- 代碼問題: 代碼中的 bug 可能會導(dǎo)致服務(wù)崩潰。
所以,排查問題的時(shí)候,要從多個(gè)方面入手,不能只盯著 Nginx 配置。