天天看點

Nginx靜态資源配置不當引發的血案

摘要:衆所周知,Nginx是目前最流行的Web Server之一,也廣泛應用于負載均衡、反向代理等服務,但使用過程中可能因為對Nginx工作原理、變量含義了解錯誤,或是參數配置不當導緻Nginx工作異常。本文介紹的就是開機廣告Nginx的參數location處理靜态檔案配置不當引發的nginx日志驟增到14G的問題排期過程。

一、問題現象及系統介紹

現象:12月15日 21:02分,正在外面吃宵夜,手機收到監控平台的一條“伺服器磁盤空間<20%”報警短信。

Nginx靜态資源配置不當引發的血案

系統介紹:為了看此文的童鞋更好了解我下面介紹的東西,這裡我先簡單介紹下福建開機廣告系統。

Nginx靜态資源配置不當引發的血案

整個系統可以分為管理平台與API兩個部分:

管理平台完成素材(包括下面提到素材圖檔名也是有放到緩存裡的)、廣告、政策、排期制作和下發等工作,提供接口将廣告政策、使用者分組等資訊同步到API;

API向機頂盒/EPG提供廣告接口,采集廣告請求日志,當STB通路EPG,EPG調用廣告請求接口擷取廣告政策(地區、分組、平台、黑白名單等政策),并在比對到政策的時候進行展示;

API節點我們是放在其中6台伺服器的23個tomcat裡面,使用nginx實作負載請求分發;圖檔伺服器我們是放在另外的3台伺服器,也是使用的nginx實作的負載請求分發。相信大家對nginx都不陌生,這裡我就不在贅述。

二、問題排查過程

2.1 初步分析

判斷一:可能是crontab未執行

一看是Nginx所在伺服器,初步判斷可能是crontab異常,沒有定期清除5天以前的日志導緻(這裡說明下:我們線上的nginx日志是每天淩晨切割access.log日志,然後通過crontab實作隻保留最近五天日志)。

2.2 深入分析

判斷二:可能圖檔同步出問題

回到家,打開SHH用戶端 檢視/data/nginx_log目錄檢視,發現access.log隻有近五天的日志,「排除原以為是crontab異情況」。

然後發現error_log很大,指令du -h error_log一看都有14G了,tail -200 error_log發現全是“/usr/local/nginx/html/resources/material/img/1511488532192.JPG”圖檔請求失敗的記錄,于是趕緊清空error_log,排除短信空間報警。

Nginx靜态資源配置不當引發的血案

心想,難道是圖檔沒有同步?

為驗證我的猜想,我打開浏覽器通路這張圖檔:http://IP:port/resources/material/img/1511488532192.JPG(上面IP指的是nginx所在伺服器IP,port是nginx.conf配置圖檔分發端口),請求幾次傳回都是404。

于是切換到主圖檔伺服器檢視,發現這張大寫圖檔存在,切換到其他兩台從圖檔伺服器,發現也是存在的(這裡說明下:我們系統的素材圖檔都是通過管理平台以接口的形式下發主圖檔伺服器,主圖檔伺服器再通過inotify+sync同步到其他兩台從圖檔伺服器),「排除圖檔同步異常情況」。

判斷三:可能是請求不到大寫字尾圖檔導緻

因為看到圖檔伺服器目錄下,唯有這幾張大寫字尾圖檔是請求異常的,那改成小寫會怎麼樣呢?接着改了下三台圖檔伺服器的圖檔大寫字尾為小寫字尾。再打開浏覽器請求,發現請求正常了,繼而判斷可能營運人員在管理平台制作廣告的時候上傳了大寫字尾的格式的圖檔,同步到API和資料庫的緩存,那麼導緻有廣告請求的從緩存查詢到的圖檔位址也就是大寫的了。

順着這個思路,我先到登入到資料庫改了下素材表圖檔大寫字尾為小寫字尾,再登入redis,準備改緩存,info指令一看,傻眼了,136萬的key數量,而我又不記得具體廣告政策key,

Nginx靜态資源配置不當引發的血案

由于沒辦法查找,那就隻能flushall清空緩存,重新開機ad-cache工程(這裡說明下:ad-cache工程的作用主要就是兩個,一是把目前符合要求的使用者、廣告政策等相關資訊初始加載到緩存,另一個是啟一個定時任務,每小時加載目前時段的政策到緩存),然後在檢視tail -f error_log檢視日志,發現還在增加之前那種大寫字尾圖檔請求失敗的錯誤,「排除圖檔字尾大寫情況」。

判斷四:可能是nginx配置不當導緻

這麼操作完還是不行,當時着實有點懵逼,我心想當時已經把廣告請求所有涉及到會查詢圖檔大寫字尾的地方改過來了,為什麼還是會有大寫字尾圖檔請求失敗的記錄?但轉念一想會不是nginx的配置有問題?

為驗證我的判斷,我先sz指令從圖檔伺服器上下載下傳了一張名為“1511488578911.JPG”的大寫字尾格式的圖檔,然後通過管理平台上傳這個“1511488578911.JPG”圖檔素材,發現這張圖檔是可以預覽的。由此更加确信就是nginx某些參數配置不當導緻。vim指令檢視配置nginx.conf,當定位到圖檔請求配置這裡的時候,

Nginx靜态資源配置不當引發的血案

發現location ~是表示區分大小寫的,而後面全是配置小寫字尾格式,于是加上JPG,使用/usr/local/nginx/sbin/nginx -s reload指令重載nginx的配置,打開浏覽器發現可以檢視到這張圖檔了,再切換到nginx日志目錄,tail -f error_log,發現日志沒有再增加,至此問題終于解決。

三、問題反思

反思一:要做到知其然并且知其是以然

對Nginx工作原理、參數含義了解不深,進而參數配置不當,導緻産生nginx日志驟增這種問題産生。

反思二:缺少一個快速定位問題的系統或工具,導緻排查的時間比較長。

當時在作出判斷三的時候,因為沒在公司,不記得廣告政策緩存key,導緻不得不直接執行flushall指令直接清空緩存,再重新刷入緩存,這樣做其實是有風險的,因為把廣告政策、使用者、分組等資訊從緩存清空之後,使用者的廣告請求隻能直接去查詢資料庫,這樣響應的時間肯定會慢了,而且緩存中還存了廣告請求的日志記錄,直接flushall就會丢失部分的廣告請求資料,影響到PV、UV統計。是以當時也是想就是有一個系統,在浏覽器直接輸入一個使用者名或是圖檔名,就能從資料庫和緩存查詢到中涉及到相關聯的資料,以可視化的形式在頁面展示,這樣定位問題也就可以更快定位問題了。于是也就是後期跟老大确認做一個問題定位輔助系統,這樣友善定位問題

四、引申

文法規則: location [=|~|~*|^~] /uri/ { … }

= 開頭表示精确比對

^~ 開頭表示uri以某個正常字元串開頭,了解為比對 url路徑即可。nginx不對url做編碼,是以請求為/static/20%/aa,可以被規則^~ /static/ /aa比對到(注意是空格)。

~ 開頭表示區分大小寫的正則比對

~* 開頭表示不區分大小寫的正則比對

!~和!~*分别為區分大小寫不比對及不區分大小寫不比對 的正則

/ 通用比對,任何請求都會比對到。

多個location配置的情況下比對順序為(參考資料而來,還未實際驗證,試試就知道了,不必拘泥,僅供參考):

首先比對 =,其次比對^~, 其次是按檔案中順序的正則比對,最後是交給 / 通用比對。當有比對成功時候,停止比對,按目前比對規則處理請求。

例子,有如下比對規則:

[plain] view plain copy

location = / {

#規則A

}

location = /login {

#規則B

location ^~ /static/ {

#規則C

}  

location ~ \.(gif|jpg|png|js|css)$ {

#規則D

location ~* \.png$ {

#規則E

location !~ \.xhtml$ {

#規則F

location !~* \.xhtml$ {

#規則G

location / {

#規則H

那麼産生的效果如下:

通路根目錄/, 比如http://localhost/ 将比對規則A

通路 http://localhost/login 将比對規則B,http://localhost/register 則比對規則H

通路 http://localhost/static/a.html 将比對規則C

通路 http://localhost/a.gif, http://localhost/b.jpg 将比對規則D和規則E,但是規則D順序優先,規則E不起作用,而 http://localhost/static/c.png 則優先比對到 規則C

通路 http://localhost/a.PNG 則比對規則E, 而不會比對規則D,因為規則E不區分大小寫。

通路 http://localhost/a.xhtml 不會比對規則F和規則G,http://localhost/a.XHTML不會比對規則G,因為不區分大小寫。規則F,規則G屬于排除法,符合比對規則但是不會比對到,是以想想看實際應用中哪裡會用到。

通路 http://localhost/category/id/1111 則最終比對到規則H,因為以上規則都不比對,這個時候應該是nginx轉發請求給後端應用伺服器,比如FastCGI(php),tomcat(jsp),nginx作為方向代理伺服器存在。

學習本就是一個不斷模仿、練習、再到最後面自己原創的過程。

雖然可能從來不能寫出超越網上通類型同主題博文,但為什麼還是要寫?

于自己而言,博文主要是自己總結。假設自己有觀衆,畢竟講是最好的學(見下圖)。

于讀者而言,筆者能在這個過程get到知識點,那就是雙赢了。

當然由于筆者能力有限,或許文中存在描述不正确,歡迎指正、補充!

感謝您的閱讀。如果本文對您有用,那麼請點贊鼓勵。

Nginx靜态資源配置不當引發的血案

  

每一個你不滿意的當下,都有一個你不曾努力的過去