使用grep和正則來分析web伺服器日誌 | 彭琪談程式設計
前兩天因為第三方遊戲伺服器掉線,導致大量使用者同時登入我的伺服器,將伺服器負載瞬間提高到200+,如此恐怖的數字讓我不得不考慮增加伺服器來抵抗問題重現,然而我的伺服器平時負載都很低,0.1都不到,增加伺服器來應付這樣短暫的風暴未免太過於浪費,於是我決定從日誌下手,找到我的**的瓶頸,希望能通過改善程式來解決這個問題。第一步,定位時間
我的日誌檔案裡包含了最近乙個禮拜的資料,然而我需要的只是風暴發生時產生的資料,總共不超過20分鐘,怎麼取呢?因為我的web伺服器採用的是標準的combined格式
而且全部是php動態請求,所以我決定從time_local下手,找到併發訪問量最高的時間段,這很容易辦到:
grep -op '12\/may\/2011(:\d)' access.log | uniq -c | sort -n > time.sort得到如下結果(部分)從18點43分開始,我的伺服器每秒需要響應120多次動態請求,而18:46:49秒更加**,211次!看來把我伺服器拖垮的,就是18點43分到18點50分這一段。
第二步, 過濾指令碼
定位好了時間,現在要做的,就是取出這一時間段的日誌再做分析,使用以下指令碼將18:43分到18:50分之間的日誌取出來
grep -p '12\/may\/2011:18:4[3-9]:\d' access.log > storm.log第三步, 找出元凶得到了storm.log,下面我便要找出拖垮我伺服器的元凶,及訪問數量最高的$request。因為$request都是 「get /***** http/1.1″ 或 「post /****」 這樣的格式, 所以可以通過簡單的正則取出$request,如下
grep -op '((?<=get\s)|(?<=post\s))[^?\s]+' storm.log | sort \(?<=get\s)這個正則叫作零寬斷言,是將要被匹配文字前面的條件,即除非前面有』get 『出現,後面的才匹配。| uniq -c | sort -n > request.sort
上面的指令碼得到以下結果:
從這張圖我們便可以找出程式方面的瓶頸了,因為上面這些請求大部分都是ajax請求,所以明顯的,像』users/getuser』、』games/getservers/sxd』這樣的資料請求完全可以被瀏覽器快取起來,而』users/logoutservice』根據我們的業務邏輯也顯得毫無必要,將這三項請求砍掉能節省將近60%的資源!
以下便是通過優化程式**後13號應對的又一次風暴結果。
看到沒,』/users/getuser』請求減少了將近一半,而』/games/getserver/sxd』則減少了近75%,總量減少了近40%!然而』/users/logoutservice』卻不盡如人意,只少了三成,我們待會再尋找其原因。
通過以上程式的優化和一些系統配置的調整,這次風暴只將我的伺服器負載公升高到了10+,並在十幾秒後就很快地平穩了下來,和前一天的200+相比,可以說成功地解決了短暫風暴的問題。
第四步,找出**
上一步遺留了乙個問題,即我明明優化了程式,去掉了不必要的』users/logoutservice』,為何在風暴中,它依然出現了那麼多次,所以我決定分析$http_referer,找出這些請求都是從哪來的。
根據日誌的格式,$http_referer前面都有乙個$body_bytes_sent、乙個空格和乙個雙引號,例如
因為$body_bytes_sent始終是個數字,這樣就可以通過以下正則來找出**
grep -p '\/users\/logoutservice?' storm.log \先過濾出logout的日誌,再通過零寬斷言找出**。得到的結果出乎我意料,來自於乙個我在上一步中已經調整過的頁面,明明去掉了不必要的』users/logoutservice』請求,為何還會重複出現?仔細觀察**後並沒發現可疑的地方,於是推測是cdn快取的問題,這些使用者用的js版本可能還是前一天的,清理快取,加上版本號,期待下次風暴來驗證這一推論!| grep -op '(?<=\d\s")[^?"]+' | sort | uniq -c | sort -n > logout.referer.sort
grep和正規表示式
常用引數 f 規則檔案 file 規則檔案 指定規則檔案,其內容含有乙個或多個規則樣式,讓grep查詢符合規則條件的檔案內容,格式為每行乙個規則樣式。grep規則表示式 錨定行的開始 如 grep匹配所有以grep開頭的行 錨定行的結束,如 grep 匹配所有以grep結尾的行 匹配 乙個非換行符的...
grep和正規表示式
grep語法 正規表示式元字元 擴充套件正規表示式元字元 grep grep global search regular expression re and print out the line 是一款文字過濾 模式 pattern 工具。作用 文字搜尋工具,根據使用者指定的 模式 對目標文字逐行進...
正規表示式和grep
正規表示式 regular expression,re 是一種字元模式,用於在查詢過程中匹配指定的字元。在大多數程式裡,正規表示式都被置於兩個正斜槓之間 例如 lv o0 e 就是由正斜槓界定的正規表示式,它將匹配被查詢的行中任何位置出現的相同模式。在正規表示式中,元字元是最重要的概念。shell萬...