如何挖掘Nginx日誌中隱藏的金礦?

  1. > 如何挖掘Nginx日誌中隱藏的金礦?

對很多開發運維人員來說,Nginx 日誌文件在被刪除前可能都不會看上一眼。但實際上,Nginx 隱藏了相當豐富的信息,或許其中便蘊含着未知的金礦等你挖掘!

寫在前面
Nginx(讀作 Engine-X)是現在最流行的負載均衡和反向代理服務器之一。如果你是一名中小微型網站的開發運維人員,很可能像我們一樣,僅 Nginx 每天就會產生上百 M 甚至數以十 G 的日誌文件。如果沒有出什麼錯誤,在被 logrotate 定期分割並滾動刪除以前,這些日誌文件可能都不會被看上一眼。
實際上,Nginx 日誌文件可以記錄的信息相當豐富,而且格式可以定製,考慮到$time_local請求時間字段幾乎必有,這是一個典型的基於文件的時間序列數據庫。Nginx 日誌被刪除以前,或許我們可以想想,其中是否蘊含着未知的金礦等待挖掘?

請求訪問分析
Nginx 中的每條記錄是一個單獨的請求,可能是某個頁面或靜態資源的訪問,也可能是某個 API 的調用。通過幾條簡單的命令,瞭解一下系統的訪問壓力:

請求總數、平均每秒請求數、峯值請求數,可以大體瞭解系統壓力,作爲系統擴容、性能及壓力測試時的直接參考。查詢特定的 URL,比如下單頁面,瞭解每天的下單狀況,導出 CSV 格式,或使用可視化工具,更直觀地瞭解一段時間內的**

> 請求、下單數據:

備註:本文使用 awk 命令處理,與 Nginx 日誌的格式有關,如果您格式不同,請酌情修改命令。本文所用的 Nginx 日誌格式:

示例:

流量速率分析
Nginx 日誌如果開啓,除了請求時間,一般會包含響應時間、頁面尺寸等字段,據此很容易計算出網絡流量、速率。
等等,你可能會有疑問,上面的請求訪問分析,這裏的流量速率分析,按時間軸畫出來,不就是監控系統乾的事兒嗎,何苦這麼麻煩查詢 Nginx 日誌?
的確如此,監控系統提供了更實時、更直觀的方式。而 Nginx 日誌文件的原始數據,可以從不同維度分析,使用得當,會如大浪淘沙般,發現屬於我們的金子。
對一般網站來說,帶寬是最珍貴的資源,可能一不小心,某些資源如文件、圖片就佔用了大量的帶寬,執行命令檢查一下:

備註:

Nginx 配置文件中日誌格式使用了 $body_sent_size,指 HTTP 響應體的大小,如果想查看整個響應的大小,應該使用變量 $sent_size。
不出意外,靜態資源、圖片類(如果還沒有放 CDN)佔據榜首,自然也是優化的重點:是否可以再壓縮,某些頁面中是否可以用縮略圖片代替等。
與之相比,後臺調用、API 接口等通常消耗更多的 CPU 資源,按照一貫“先衡量、再優化”的思路,可以根據響應時間大體瞭解某個 URL 佔用的 CPU 時間:

不對,發現一個問題:由於擁有服務號、App、PC 瀏覽器等多種前端,並且使用不規範,URL 的格式可能亂七八糟。比如/page/a頁面,有的帶有.html 後綴,有的未帶,有的請求路徑則帶有參數;分類頁 /categories/food 帶有slug等信息;訂單、詳情或個人中心的 URL 路徑則有ID等標記...。
藉助 sed 命令,通過三個方法對 URL 格式進行歸一化處理:去掉所有的參數;去掉.html及.json後綴;把數字替換爲*。可以得到更準確的統計結果,:
這裏使用了擴展正則表達式,GNU sed 的參數爲 -r,BSD sed 的參數爲 -E。
那些累計佔用了更多響應時間的請求,通常也耗用了更多的 CPU 時間,是性能優化重點照顧的對象。

慢查詢分析

“服務號剛推送了文章,有用戶反映點開很慢”,你剛端起桌子上的水杯,就聽到產品經理的大嗓門從辦公室角落呼嘯而來。“用戶用的什麼網絡”,你一邊問着,一邊打開服務號親自嘗試一下。是用戶網絡環境不好,還是後臺系統有了訪問壓力?是這一個用戶慢,還是很多用戶都慢?你一邊腦子裏在翻騰,一邊又打開命令行去查看日誌。
與 PC 瀏覽器相比,微信服務號在網絡環境、頁面渲染上有較大的掣肘,在緩存策略上也不如 APP 自如,有時會遇到詭異的問題。如果手裏恰好有 Nginx 日誌,能做點什麼呢?
考慮一下 MySQL 數據庫,可以打開慢查詢功能,定期查找並優化慢查詢,與此類似,Nginx 日誌中的響應時間,不相當於自帶慢查詢功能嘛。利用這一特性,我們分步進行慢查詢分析:

第一步:是不是用戶的網絡狀況不好?根據既往的經驗,如果只有少量的請求較慢,而前後其他 IP 的請求都較快,通常是用戶手機或網絡狀況不佳引起的。最簡單的方法,統計慢查詢所佔比例:
慢查詢所佔比例極低,再根據用戶手機型號、訪問時間、訪問頁面等信息看能否定位到指定的請求,結合前後不同用戶的請求,就可以確定是否用戶的網絡狀況不好了。

第二步:
是不是應用系統的瓶頸?對比應用服務器的返回時間 ($upstream_response_time 字段),與 Nginx 服務器的處理時間 ($request_time 字段),先快速排查是否某一臺服務器抽風。
我們遇到過類似問題,平均響應時間 90ms,還算正常,但某臺服務器明顯變慢,平均響應時間達到了 200ms,影響了部分用戶的訪問體驗。
不幸,市場部此次推廣活動,訪問壓力增大,所有服務器都在變慢,更可能是應用系統的性能達到了瓶頸。如果此時帶寬都沒跑滿,在硬件擴容之前,考慮優化重點 API、緩存、靜態化策略吧,達到一個基本的要求:“優化系統,讓瓶頸落到帶寬上”。

第三步:
應用系統沒有瓶頸,是帶寬的問題?快速查看一下每秒的流量:
峯值帶寬接近出口帶寬最大值了,幸福的煩惱,利用前面介紹的不同 URL 的帶寬統計,做定向優化,或者加帶寬吧。
還能做哪些優化?
SEO 團隊抱怨優化了那麼久,爲什麼頁面索引量和排名上不去。打印出不同爬蟲的請求頻次($http_user_agent),或者查看某個特定的頁面,最近有沒有被爬蟲爬過:
數據告訴我們,頁面索引量上不去,不一定是某個爬蟲未檢索到頁面,更多的是其他原因。
市場團隊要上一個新品並且做促銷活動,你建議避開週一週五,因爲週三週四的轉化率更高:

週三、週四的轉換率比周末高不少,可能跟平臺的發貨週期有關,客戶週三四下單,希望週末就能收到貨,開始快樂的週末。你猜測到用戶的心理和期望,連數據一起交市場品團隊,期待更好地改善。
這樣的例子可以有很多。事實上,上述分析限於 Nginx 日誌,如果有系統日誌,並且日誌格式定義良好,可以做的事情遠不止於此:這是一個時間序列數據庫,可以查詢 IT 系統的運行情況,可以分析營銷活動的效果,也可以預測業務數據的趨勢;這是一個比較小但夠用的大數據源,運用你學會的大數據分析方法,也可以像滴滴那樣,分並預測不同天氣、時間段下不同地區的車輛供需,並作出優化。

幾點建議

規範日誌格式。這是很多團隊容易忽略的地方,有時候多一個空格會讓日誌分析的複雜度大爲增加。
無論如何,使用時間戳字段。以時間序列的方式看待日誌文件,這也是很多公司把系統日誌直接寫入到時間序列數據庫的原因;
如有可能,記錄以下字段:用戶(或者客戶端)標識、單次請求標識、應用標識(如果單次請求會走到多個應用)。能夠方便地查出用戶鏈路、請求鏈路,是排查錯誤請求、分析用戶行爲的基礎;
關注寫的操作。就像業務建模時,需要特別關注具有時標性、狀態會發生改變的模型一樣,任何寫的操作,都應記錄到日誌系統中。萬一某個業務出錯,不但可以通過業務模型復演,也可以通過日誌系統復演。
規範 URL 格式。這一點同樣容易遭到忽略,商品詳情頁面要不要添加"?from=XXX"來源參數?支付頁面採用路徑標記“payment/alipay”,還是參數標記“/payment?type=alipay”更合適?區別細微但影響不可忽略。
技術團隊應該像對待協議一樣對待這些規範。仔細定義並嚴格遵守,相當於拿到了金礦的鑰匙。
還需要尋找一個合適的日誌分析工具,基於 Python、Go、Lua,都有免費的日誌分析工具可供使用;想更輕量,準備幾條常用的 shell 腳本,比如作者整理了一些到 GitHub 的這個項目上(https://github.com/aqingsao/nana);或者基於 ELK 技術棧,把 Nginx 訪問日誌、業務日誌統一存儲,並通過 Kibana 進行不同維度的聚合分析,都是不錯的辦法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章