Nginx是一個開源通惫、免費(fèi)、高性能的HTTP和反向代理服務(wù)器,也可以用于IMAP/POP3代理服務(wù)器涧尿。充分利用Nginx的特性系奉,可以有效解決流量高并發(fā)請求、cc攻擊等問題姑廉。
本文探討了電商場景下Nginx的監(jiān)控方案缺亮,并將使用過程中遇到的問題和解決方案與大家一起分享。
一桥言、對于Nginx你一定了解的基礎(chǔ)
1萌踱、特性
作為Web服務(wù)器,Nginx不免要與Apache進(jìn)行比較号阿。相比Apache服務(wù)器并鸵,Nginx因其采用的異步非阻塞工作模型,使其具備高并發(fā)扔涧、低資源消耗的特性园担,高度模塊化設(shè)計使Nginx具備很好的擴(kuò)展性;在處理靜態(tài)文件枯夜、反向代理請求等方面弯汰,Nginx表現(xiàn)出很大的優(yōu)勢。
2湖雹、常見的使用方式
Nginx可以作為反向代理服務(wù)器來轉(zhuǎn)發(fā)用戶請求咏闪;并能夠在處理請求的過程中實(shí)現(xiàn)后端實(shí)例負(fù)載均衡,實(shí)現(xiàn)分發(fā)請求的功能摔吏;也可將Nginx配置為本地靜態(tài)服務(wù)器鸽嫂,處理靜態(tài)請求。
二征讲、對于Nginx你需要懂得的監(jiān)控
1据某、監(jiān)控指標(biāo)梳理
Nginx處理請求的全過程應(yīng)被監(jiān)控起來,以便我們及時發(fā)現(xiàn)服務(wù)是否能夠正常運(yùn)轉(zhuǎn)稳诚。Nginx處理請求的過程被詳細(xì)地記錄在access.log以及error.log文件中哗脖,我們給出以下需要監(jiān)控的關(guān)鍵指標(biāo):
2、監(jiān)控實(shí)踐
從延遲扳还、錯誤才避、流量以及飽和度四個指標(biāo)對Nginx監(jiān)控實(shí)踐進(jìn)行說明。
延遲監(jiān)控:
延遲監(jiān)控主要關(guān)注對$request_time的監(jiān)控氨距,并繪制tp指標(biāo)圖桑逝,來確認(rèn)tp99指標(biāo)值。另外俏让,我們還可以增加對$upstream_response_time指標(biāo)的監(jiān)控楞遏,來輔助定位延遲問題的原因茬暇。
下圖展示了過去15min內(nèi)Nginx處理用戶請求的時間:
可以看出用戶90%的請求可以在0.1s內(nèi)處理完成,99%的請求可以在0.3s內(nèi)完成寡喝。根據(jù)tp指標(biāo)值糙俗,并結(jié)合具體業(yè)務(wù)對延遲的容忍度,來設(shè)置延遲的報警閾值预鬓。
錯誤監(jiān)控:
Nginx作為web服務(wù)器巧骚,不但要對Nginx本身運(yùn)行狀態(tài)進(jìn)行監(jiān)控,還必須對Nginx的各類錯誤響應(yīng)進(jìn)行監(jiān)控格二,HTTP錯誤狀態(tài)碼以及error.log中記錄的錯誤詳細(xì)日志都應(yīng)被監(jiān)控起來以協(xié)助解決問題劈彪。
1)基于HTTP語義的Nginx端口監(jiān)控
單純的Nginx端口監(jiān)控?zé)o法反映服務(wù)真實(shí)運(yùn)行狀態(tài),我們要關(guān)注的是Nginx本身存活以及是否可以正常提供服務(wù)顶猜;基于我們的實(shí)踐沧奴,我們推薦用語義監(jiān)控代替端口監(jiān)控,即從Nginx本機(jī)以http://local_ip:port/的方式進(jìn)行訪問长窄,校驗(yàn)返回的數(shù)據(jù)格式滔吠、內(nèi)容及HTTP狀態(tài)碼是否符合預(yù)期。
2)錯誤碼監(jiān)控
必須添加對諸如500/502/504等5xx服務(wù)類錯誤狀態(tài)碼的監(jiān)控抄淑,它們告訴我們服務(wù)本身出現(xiàn)了問題屠凶。
5xx類錯誤每分鐘出現(xiàn)的頻率應(yīng)該在個位數(shù)驰后,太多的5xx應(yīng)及時排查問題并解決肆资;4xx類錯誤,在協(xié)助解決一些非預(yù)期的權(quán)限錯誤灶芝、資源丟失或性能等問題上可以給予幫助郑原;可以選擇性得對301/302重定向類監(jiān)控,應(yīng)對特殊配置跳轉(zhuǎn)的監(jiān)控夜涕,如后端服務(wù)器返回5xx后犯犁,Nginx配置重定向跳轉(zhuǎn)并返回跳轉(zhuǎn)后的請求結(jié)果。
狀態(tài)碼監(jiān)控
3)對錯誤日志監(jiān)控
Nginx內(nèi)部實(shí)現(xiàn)了對請求處理錯誤的詳細(xì)記錄女器,并保存在error.log文件中酸役。錯誤類型有很多種,我們主要針對關(guān)鍵的驾胆、能體現(xiàn)服務(wù)端異常的錯誤進(jìn)行采集并監(jiān)控涣澡,以協(xié)助我們進(jìn)行故障定位:
錯誤日志信息
流量監(jiān)控:
1)Nginx所接受請求總量的監(jiān)控
關(guān)注流量波動周期,并捕獲流量突增丧诺、突降的情況入桂;通常穩(wěn)態(tài)下流量低峰和高峰浮動20%需要關(guān)注下原因;對于有明顯波動周期的服務(wù)驳阎,我們也可以采用同環(huán)比增漲/降低的告警策略抗愁,來及時發(fā)現(xiàn)流量的變化馁蒂。
下圖為京東云某平臺一周內(nèi)的流量波動圖:
pv流量圖
流量存在明顯低峰和高峰并有天級別的周期性,基于網(wǎng)站運(yùn)行特性蜘腌,根據(jù)低峰沫屡、高峰的值來監(jiān)控網(wǎng)站流量的波動,并通過自身的監(jiān)控儀表盤配置網(wǎng)站關(guān)鍵頁面的流量圖撮珠,以協(xié)助故障排查:
關(guān)鍵流量圖
2)對網(wǎng)卡IO等機(jī)器級別流量的進(jìn)行監(jiān)控
可以及時發(fā)現(xiàn)服務(wù)器硬件負(fù)載的壓力谁鳍,當(dāng)Nginx被用于搭建文件服務(wù)器時,此監(jiān)控指標(biāo)需要我們尤為關(guān)注劫瞳。
網(wǎng)卡流量圖
飽和度監(jiān)控:
Google SRE中提到倘潜,飽和度應(yīng)關(guān)注服務(wù)對資源的利用率以及服務(wù)在當(dāng)前運(yùn)行情況下還可以承受多少負(fù)載。
Nginx是低資源消耗的高性能服務(wù)器志于,但諸如在電商場景下涮因,新產(chǎn)品搶購則會在短時間內(nèi)造成cpu利用率、請求連接數(shù)伺绽、磁盤寫入的飆升养泡;cpu利用率還要考慮通過worker_cpu_affinity綁定worker進(jìn)程到特定cpu核心的使用情況,處理高流量時奈应,該配置可以減少cpu切換的性能損耗澜掩。
Nginx可以接受的最大連接數(shù)在配置文件nginx.conf中由worker_processes和worker_connections
兩個參數(shù)的乘積決定;通過Nginx自帶的模塊http_stub_status_module 可以對Nginx的實(shí)時運(yùn)行信息進(jìn)行監(jiān)控:
因我們更關(guān)心當(dāng)前Nginx運(yùn)行情況杖挣,不對已處理的請求做過多關(guān)注肩榕,所以我們只對如下指標(biāo)進(jìn)行采集監(jiān)控:
指標(biāo)含義
三、基于開源軟件搭建Nginx可視化監(jiān)控系統(tǒng)
1惩妇、采用Elasticsearch + Logstash + Kibana搭建可視化日志監(jiān)控
針對以上四個監(jiān)控黃金指標(biāo)株汉,搭建的ELK棧儀表盤,設(shè)置常用的Nginx日志過濾規(guī)則歌殃,以便可以快速定位分析問題:
ELK棧架構(gòu)圖
ELK儀表盤
2)采用Kibana + Elasticsearch + Rsyslog + Grafana搭建可視化日志監(jiān)控
相較于kibana能快速地對日志進(jìn)行檢索乔妈,Grafana則在數(shù)據(jù)展示方面體現(xiàn)了更多的靈活性,某些情況下二者可以形成互補(bǔ):
Grafana可視化架構(gòu)圖
Grafana儀表盤
我們在實(shí)踐中實(shí)現(xiàn)上述兩種架構(gòu)的Nginx日志可視化監(jiān)控:
從需求本身來講氓皱,ELK棧模型可以提供實(shí)時的日志檢索路召,各種日志規(guī)則的過濾和數(shù)據(jù)展示,基本可以滿足Nginx日志監(jiān)控的需求波材;
Grafana架構(gòu)模型無法進(jìn)行日志檢索和瀏覽股淡,但提供了角色權(quán)限的功能,來防護(hù)一些敏感數(shù)據(jù)的訪問各聘;
另外揣非,Grafana更為豐富的圖表類型和數(shù)據(jù)源支持,使其具有更多的應(yīng)用場景躲因。
四早敬、基于Nginx監(jiān)控發(fā)現(xiàn)并定位問題案例
案例1:大流量沖擊
問題:某平臺忌傻,進(jìn)行了一次新產(chǎn)品的搶購活動「慵啵活動期間因流量飆升導(dǎo)致商品詳情頁水孩、下單等核心功能處理耗時增加的情況:
PV飆升圖
解決:訂單監(jiān)控及Nginx的PV、請求時間等監(jiān)控指標(biāo)發(fā)出報警后琐驴,運(yùn)維人員迅速通過自建的ELK監(jiān)控儀表盤俘种,關(guān)注網(wǎng)站流量變化,查看用戶請求top
IP绝淡、top
URL宙刘;發(fā)現(xiàn)存在大量黃牛的惡意搶購行為,導(dǎo)致服務(wù)后端處理延時牢酵。因此悬包,我們通過降低高防產(chǎn)品、Nginx限流配置中相關(guān)接口防攻擊閾值馍乙,及時攔截了對系統(tǒng)負(fù)載造成壓力的刷單行為布近,保障了新品促銷活動順利開展。
案例2:Nginx錯誤狀態(tài)碼警示服務(wù)異常
問題:某平臺進(jìn)行后端服務(wù)器調(diào)整丝格,某個Nginx的upstream指向的后端服務(wù)器配置錯誤撑瞧,指向了一個非預(yù)期的后端服務(wù);當(dāng)錯誤的配置被發(fā)布到線上后显蝌,網(wǎng)站開始出現(xiàn)概率性的異常预伺,并伴有500和302錯誤狀態(tài)碼數(shù)量的飆升。
302錯誤碼統(tǒng)計
解決:Nginx錯誤狀態(tài)碼告警后琅束,通過ELK平臺過濾302錯誤碼下用戶請求的URL扭屁,發(fā)現(xiàn)請求錯誤的URL均與后端的某個模塊相關(guān),該請求都被重定向到了網(wǎng)站首頁涩禀;進(jìn)一步定位發(fā)現(xiàn),某臺Nginx的指向了錯誤的后端服務(wù)器然眼,導(dǎo)致服務(wù)器返回大量500錯誤艾船,但因Nginx配置中對500錯誤做了重定向,并因此產(chǎn)生了很多302狀態(tài)碼高每。
在后續(xù)改進(jìn)中屿岂,我們通過升級Nginx,采用openresty+lua方式來對后端服務(wù)器進(jìn)行健康監(jiān)測鲸匿,以動態(tài)更新upstream中的server爷怀,可以快速摘除異常的后端服務(wù)器,達(dá)到快速止損的目的:
配置upstream健康監(jiān)測
案例3:nginx服務(wù)器磁盤空間耗盡導(dǎo)致服務(wù)異常
問題:Nginx作為圖片服務(wù)器前端带欢,某天其中一實(shí)例在生產(chǎn)環(huán)境無任何變更的情況下收到報警提示:500狀態(tài)碼在整體流量中占比過高运授。
解決:快速將此機(jī)器從生產(chǎn)環(huán)境中摘除烤惊,不再提供服務(wù);
經(jīng)排查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請求的部分或者全部內(nèi)容暫存到client_body_temp_path目錄,當(dāng)磁盤空間被占滿時逗宜,產(chǎn)生了以上的報錯雄右。
最終,我們確認(rèn)了本次異常是產(chǎn)品后升級支持上傳的圖片大小由15MB改為50MB纺讲,并且運(yùn)營方進(jìn)行了新產(chǎn)品推廣活動擂仍,用戶上傳圖片量激增快速打滿磁盤空間所致。
文章來源:京東運(yùn)維部