502 Bad Gateway的處理

網站每天有大約1億的流量(請求數),目前只有幾臺機器,壓力比較大。

最近,網站訪問的時候經常出現502 Bad Gateway的錯誤提示,有幾個同事處理了幾個星期沒有找到問題的原因,昨天史哥讓我看看日誌,看看能不能找出點頭緒。

雖然是nginx反向代理報的錯,但很明顯是後面的php服務器出了問題了,一般就是請求超時,之前用php取數據的數據的時候沒有設置超時時間,結果導致請求時間過長,fast cgi進程數增加,大部分的php-cgi的資源都在等待外部接口返回數據,導致新的請求得不到處理。解決方案就是所有的取數據的工作要麼:1)做成crontab的形式去取,2)在php代碼裏面去的時候,一定要設置超時時間。

一般的PHP網站的架構差不多類似於下圖:

image

整個系統併發數的瓶頸在php-cgi上,一般也是200r/s,但是由於程序或者其他原因導致處理請求的時間過長的話(如:3s-5s),則php-cgi處理的能力就會下降3-5倍,新的請求無法得到處理,超時也是難免了。

那麼,當遇到類似的問題時,應該如何排查呢?

個人覺着,可以從nginx的error log查起。雖然是提供web服務的php端出的問題,但是web日誌對問題的記錄卻沒有幫助,因爲處理請求的時間長對於web服務器來說並不是錯誤。nginx反向代理則會記下所有請求超時的鏈接,會對問題的排查幫助很大。

假設當1秒鐘同時過來200個請求的時候,可能有50個請求是有問題的,這50個請求會佔用5秒的時間處理,當第2秒的200個請求過來的時候,有50個還沒處理完,所以有50個請求會得不到資源來處理,以此類推,當第4秒的時候,就可能會有大部分的資源都用在超時的請求上了,502也就在所難免了。

nginx的error log的大部分的超時請求應該是有問題的請求(本身就超時的請求),也附帶有一部分的正常請求(因得不到資源而超時的請求),在分析排查原因的時候,不要被第二種情況干擾了,對這些請求的鏈接做一下歸併,找出數目最多的來,差不多就是有問題的請求。

本次線上的問題是由於輸入參數爲空導致數據庫查詢返回條目過多,消耗了大量的資源導致的。在程序上加上空參數驗證即可解決問題。

出問題的同事被史哥“責令”買水給大夥喝。

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