對不少開發運維人員來講,Nginx 日誌文件在被刪除前可能都不會看上一眼。但實際上,Nginx 隱藏了至關豐富的信息,或許其中便蘊含着未知的金礦等你挖掘!html
寫在前面
Nginx(讀做 Engine-X)是如今最流行的負載均衡和反向代理服務器之一。若是你是一名中小微型網站的開發運維人員,極可能像咱們同樣,僅 Nginx 天天就會產生上百 M 甚至數以十 G 的日誌文件。若是沒有出什麼錯誤,在被 logrotate 按期分割並滾動刪除之前,這些日誌文件可能都不會被看上一眼。
實際上,Nginx 日誌文件能夠記錄的信息至關豐富,並且格式能夠定製,考慮到$time_local請求時間字段幾乎必有,這是一個典型的基於文件的時間序列數據庫。Nginx 日誌被刪除之前,或許咱們能夠想一想,其中是否蘊含着未知的金礦等待挖掘?前端請求訪問分析
Nginx 中的每條記錄是一個單獨的請求,多是某個頁面或靜態資源的訪問,也多是某個 API 的調用。經過幾條簡單的命令,瞭解一下系統的訪問壓力:git
請求總數、平均每秒請求數、峯值請求數,能夠大致瞭解系統壓力,做爲系統擴容、性能及壓力測試時的直接參考。查詢特定的 URL,好比下單頁面,瞭解天天的下單情況,導出 CSV 格式,或使用可視化工具,更直觀地瞭解一段時間內的**github
> 請求、下單數據:正則表達式
備註:本文使用 awk 命令處理,與 Nginx 日誌的格式有關,若是您格式不一樣,請酌情修改命令。本文所用的 Nginx 日誌格式:shell
示例:數據庫
流量速率分析
Nginx 日誌若是開啓,除了請求時間,通常會包含響應時間、頁面尺寸等字段,據此很容易計算出網絡流量、速率。
等等,你可能會有疑問,上面的請求訪問分析,這裏的流量速率分析,按時間軸畫出來,不就是監控系統乾的事兒嗎,何苦這麼麻煩查詢 Nginx 日誌?
的確如此,監控系統提供了更實時、更直觀的方式。而 Nginx 日誌文件的原始數據,能夠從不一樣維度分析,使用得當,會如大浪淘沙般,發現屬於咱們的金子。
對通常網站來講,帶寬是最珍貴的資源,可能一不當心,某些資源如文件、圖片就佔用了大量的帶寬,執行命令檢查一下:json
備註:瀏覽器
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),或者查看某個特定的頁面,最近有沒有被爬蟲爬過:
數據告訴咱們,頁面索引量上不去,不必定是某個爬蟲未檢索到頁面,更多的是其餘緣由。
市場團隊要上一個新品而且作促銷活動,你建議避開週一週五,由於週三週四的轉化率更高:
周3、週四的轉換率比周末高很多,可能跟平臺的發貨週期有關,客戶週三四下單,但願週末就能收到貨,開始快樂的週末。你猜想到用戶的心理和指望,連數據一塊兒交市場品團隊,期待更好地改善。
這樣的例子能夠有不少。事實上,上述分析限於 Nginx 日誌,若是有系統日誌,而且日誌格式定義良好,能夠作的事情遠不止於此:這是一個時間序列數據庫,能夠查詢 IT 系統的運行狀況,能夠分析營銷活動的效果,也能夠預測業務數據的趨勢;這是一個比較小但夠用的大數據源,運用你學會的大數據分析方法,也能夠像滴滴那樣,分並預測不一樣天氣、時間段下不一樣地區的車輛供需,並做出優化。
幾點建議
規範日誌格式。這是不少團隊容易忽略的地方,有時候多一個空格會讓日誌分析的複雜度大爲增長。
不管如何,使用時間戳字段。以時間序列的方式看待日誌文件,這也是不少公司把系統日誌直接寫入到時間序列數據庫的緣由;
若有可能,記錄如下字段:用戶(或者客戶端)標識、單次請求標識、應用標識(若是單次請求會走到多個應用)。可以方便地查出用戶鏈路、請求鏈路,是排查錯誤請求、分析用戶行爲的基礎;
關注寫的操做。就像業務建模時,須要特別關注具備時標性、狀態會發生改變的模型同樣,任何寫的操做,都應記錄到日誌系統中。萬一某個業務出錯,不但能夠經過業務模型復演,也能夠經過日誌系統復演。
規範 URL 格式。這一點一樣容易遭到忽略,商品詳情頁面要不要添加"?from=XXX"來源參數?支付頁面採用路徑標記「payment/alipay」,仍是參數標記「/payment?type=alipay」更合適?區別細微但影響不可忽略。
技術團隊應該像對待協議同樣對待這些規範。仔細定義並嚴格遵照,至關於拿到了金礦的鑰匙。
還須要尋找一個合適的日誌分析工具,基於 Python、Go、Lua,都有免費的日誌分析工具可供使用;想更輕量,準備幾條經常使用的 shell 腳本,好比做者整理了一些到 GitHub 的這個項目上(https://github.com/aqingsao/nana);或者基於 ELK 技術棧,把 Nginx 訪問日誌、業務日誌統一存儲,並經過 Kibana 進行不一樣維度的聚合分析,都是不錯的辦法。