深度 | 掌握Nginx監(jiān)控運維,這一篇足矣!
Nginx 是一個開源、免費、高性能的 HTTP 和反向代理服務器,也可以用于 IMAP/POP3 代理服務器。充分利用 Nginx 的特性,可以有效解決流量高并發(fā)請求、cc 攻擊等問題。
本文探討了電商場景下 Nginx 的監(jiān)控方案,并將使用過程中遇到的問題和解決方案與大家一起分享。
Nginx 特性
作為 Web 服務器,Nginx 不免要與 Apache 進行比較。
相比 Apache 服務器,Nginx 因其采用的異步非阻塞工作模型,使其具備高并發(fā)、低資源消耗的特性,高度模塊化設計使 Nginx 具備很好的擴展性;在處理靜態(tài)文件、反向代理請求等方面,Nginx 表現(xiàn)出很大的優(yōu)勢。
Nginx 常見的使用方式
Nginx 可以作為反向代理服務器來轉發(fā)用戶請求;并能夠在處理請求的過程中實現(xiàn)后端實例負載均衡,實現(xiàn)分發(fā)請求的功能;也可將 Nginx 配置為本地靜態(tài)服務器,處理靜態(tài)請求。
Nginx 監(jiān)控
監(jiān)控指標梳理
Nginx 處理請求的全過程應被監(jiān)控起來,以便我們及時發(fā)現(xiàn)服務是否能夠正常運轉。
Nginx 處理請求的過程被詳細地記錄在 access.log 以及 error.log 文件中,我們給出以下(表 1)需要監(jiān)控的關鍵指標:
表1:關鍵指標
監(jiān)控實踐
下面從延遲、錯誤、流量以及飽和度四個指標對 Nginx 監(jiān)控實踐進行說明。
延遲監(jiān)控
延遲監(jiān)控主要關注對 $request_time 的監(jiān)控,并繪制 TP 指標圖,來確認 TP99 指標值。
另外,我們還可以增加對 $upstream_response_time 指標的監(jiān)控,來輔助定位延遲問題的原因。
圖 1:TP 指標
圖 1 展示了過去 15min 內 Nginx 處理用戶請求的時間,可以看出用戶 90% 的請求可以在 0.1s 內處理完成,99% 的請求可以在 0.3s 內完成。
根據 TP 指標值,并結合具體業(yè)務對延遲的容忍度,來設置延遲的報警閾值。
錯誤監(jiān)控
Nginx 作為 Web 服務器,不但要對 Nginx 本身運行狀態(tài)進行監(jiān)控,還必須對 Nginx 的各類錯誤響應進行監(jiān)控,HTTP 錯誤狀態(tài)碼以及 error.log 中記錄的錯誤詳細日志都應被監(jiān)控起來以協(xié)助解決問題。
①基于 HTTP 語義的 Nginx 端口監(jiān)控
單純的 Nginx 端口監(jiān)控無法反映服務真實運行狀態(tài),我們要關注的是 Nginx 本身存活以及是否可以正常提供服務。
基于我們的實踐,我們推薦用語義監(jiān)控代替端口監(jiān)控,即從 Nginx 本機以 http://local_ip:port/ 的方式進行訪問,校驗返回的數(shù)據格式、內容及 HTTP 狀態(tài)碼是否符合預期。
②錯誤碼監(jiān)控
必須添加對諸如 500/502/504 等 5xx 服務類錯誤狀態(tài)碼的監(jiān)控,它們告訴我們服務本身出現(xiàn)了問題。
圖 2:狀態(tài)碼監(jiān)控
5xx 類錯誤每分鐘出現(xiàn)的頻率應該在個位數(shù),太多的 5xx 應及時排查問題并解決;4xx 類錯誤,在協(xié)助解決一些非預期的權限錯誤、資源丟失或性能等問題上可以給予幫助。
可以選擇性得對 301/302 重定向類監(jiān)控,應對特殊配置跳轉的監(jiān)控,如后端服務器返回 5xx 后,Nginx 配置重定向跳轉并返回跳轉后的請求結果。
③對錯誤日志監(jiān)控
Nginx 內部實現(xiàn)了對請求處理錯誤的詳細記錄,并保存在 error.log 文件中。
錯誤類型有很多種,我們主要針對關鍵的、能體現(xiàn)服務端異常的錯誤進行采集并監(jiān)控,以協(xié)助我們進行故障定位:
表 2:錯誤日志信息
流量監(jiān)控
①Nginx 所接受請求總量的監(jiān)控
關注流量波動周期,并捕獲流量突增、突降的情況;通常穩(wěn)態(tài)下流量低峰和高峰浮動 20% 需要關注下原因。
對于有明顯波動周期的服務,我們也可以采用同環(huán)比增漲/降低的告警策略,來及時發(fā)現(xiàn)流量的變化。
圖 3:PV 流量圖
圖 4:關鍵流量圖
圖 3 為京東云某平臺一周內的流量波動圖,流量存在明顯低峰和高峰并有天級別的周期性。
基于網站運行特性,根據低峰、高峰的值來監(jiān)控網站流量的波動,并通過自身的監(jiān)控儀表盤配置網站關鍵頁面的流量圖(圖 4),以協(xié)助故障排查。
圖 5:網卡流量圖
②對網卡 IO 等機器級別流量進行監(jiān)控
可以及時發(fā)現(xiàn)服務器硬件負載的壓力,當 Nginx 被用于搭建文件服務器時,此監(jiān)控指標需要我們尤為關注。
飽和度監(jiān)控
Google SRE 中提到,飽和度應關注服務對資源的利用率以及服務在當前運行情況下還可以承受多少負載。
Nginx 是低資源消耗的高性能服務器,但諸如在電商場景下,新產品搶購會在短時間內造成 CPU 利用率、請求連接數(shù)、磁盤寫入的飆升。
CPU 利用率還要考慮通過 worker_cpu_affinity 綁定 Worker 進程到特定 CPU 核心的使用情況,處理高流量時,該配置可以減少 CPU 切換的性能損耗。
Nginx 可以接受的最大連接數(shù)在配置文件 nginx.conf 中由 worker_processes 和 worker_connections 兩個參數(shù)的乘積決定。
圖 6
通過 Nginx 自帶的模塊 http_stub_status_module 可以對 Nginx 的實時運行信息(圖 6)進行監(jiān)控。
因我們更關心當前 Nginx 運行情況,不對已處理的請求做過多關注,所以我們只對如下指標進行采集監(jiān)控:
表 3:指標含義
基于開源軟件搭建 Nginx 可視化監(jiān)控系統(tǒng)
①采用 Elasticsearch+Logstash+Kibana 搭建可視化日志監(jiān)控

圖 7:ELK 棧架構圖
針對以上四個監(jiān)控黃金指標,搭建的 ELK 棧儀表盤,設置常用的 Nginx 日志過濾規(guī)則(圖 8),以便可以快速定位分析問題。
圖 8:ELK 儀表盤
②采用 Kibana+Elasticsearch+Rsyslog+Grafana 搭建可視化日志監(jiān)控
圖 9:Grafana 可視化架構圖
相較于 Kibana 能快速地對日志進行檢索,Grafana 則在數(shù)據展示方面體現(xiàn)了更多的靈活性,某些情況下二者可以形成互補。
圖 10:Grafana 儀表盤
我們在實踐中實現(xiàn)上述兩種架構的 Nginx 日志可視化監(jiān)控;從需求本身來講,ELK 棧模型可以提供實時的日志檢索,各種日志規(guī)則的過濾和數(shù)據展示,基本可以滿足 Nginx 日志監(jiān)控的需求。
Grafana 架構模型無法進行日志檢索和瀏覽,但提供了角色權限的功能,來防護一些敏感數(shù)據的訪問。
另外,Grafana 更為豐富的圖表類型和數(shù)據源支持,使其具有更多的應用場景。
基于 Nginx 監(jiān)控發(fā)現(xiàn)并定位問題案例
案例 1:大流量沖擊
問題:某平臺,進行了一次新產品的搶購活動。活動期間因流量飆升導致商品詳情頁、下單等核心功能處理耗時增加的情況。
圖 11:PV 飆升圖
解決:訂單監(jiān)控及 Nginx 的 PV、請求時間等監(jiān)控指標發(fā)出報警后,運維人員迅速通過自建的 ELK 監(jiān)控儀表盤,關注網站流量變化,查看用戶請求 top IP、top URL;發(fā)現(xiàn)存在大量黃牛的惡意搶購行為,導致服務后端處理延時。
因此,我們通過降低高防產品、Nginx 限流配置中相關接口防攻擊閾值,及時攔截了對系統(tǒng)負載造成壓力的刷單行為,保障了新品促銷活動順利開展。
案例 2:Nginx 錯誤狀態(tài)碼警示服務異常
問題:某平臺進行后端服務器調整,某個 Nginx 的 upstream 指向的后端服務器配置錯誤,指向了一個非預期的后端服務。
當錯誤的配置被發(fā)布到線上后,網站開始出現(xiàn)概率性的異常,并伴有 500 和 302 錯誤狀態(tài)碼數(shù)量的飆升。
圖 12:302 錯誤碼統(tǒng)計
解決:Nginx 錯誤狀態(tài)碼告警后,通過 ELK 平臺過濾 302 錯誤碼下用戶請求的 URL,發(fā)現(xiàn)請求錯誤的 URL 均與后端的某個模塊相關,該請求都被重定向到了網站首頁。
進一步定位發(fā)現(xiàn),某臺 Nginx 指向了錯誤的后端服務器,導致服務器返回大量 500 錯誤,但因 Nginx 配置中對 500 錯誤做了重定向,并因此產生了很多 302 狀態(tài)碼。
圖 13:配置 upstream 健康監(jiān)測
在后續(xù)改進中,我們通過升級 Nginx,采用 openresty+lua 方式來對后端服務器進行健康監(jiān)測(圖 13),以動態(tài)更新 upstream 中的 server,可以快速摘除異常的后端服務器,達到快速止損的目的。
案例 3:Nginx 服務器磁盤空間耗盡導致服務異常
問題:Nginx 作為圖片服務器前端,某天其中一實例在生產環(huán)境無任何變更的情況下收到報警提示:500 狀態(tài)碼在整體流量中占比過高。
解決:快速將此機器從生產環(huán)境中摘除,不再提供服務,經排查 Nginx 錯誤日志發(fā)現(xiàn)如下報錯:
- open() "/home/work/upload/client_body_temp/0000030704" failed (28: No space left on device)
Nginx 處理請求時,會將客戶端 POST 長度超過 client_body_buffer_size 請求的部分或者全部內容暫存到 client_body_temp_path 目錄,當磁盤空間被占滿時,產生了以上的報錯。
最終,我們確認了本次異常是產品升級后支持上傳的圖片大小由 15MB 改為 50MB,并且運營方進行了新產品推廣活動,用戶上傳圖片量激增快速打滿磁盤空間所致。