解决一个偶现的503 bug,花了俺不少时间
概述
在3月2日晚上,大概8點左右,本想打道回府,回家休息,突然被人在bug群@了一下,說是管理后臺,訪問不了,界面上出現(xiàn)了:
503 service temporarily unavailable 復制代碼我趕緊嘗試訪問了一下,確實如此,但不是每次都不行,而是偶發(fā)503的錯誤提示。當時我是沒有立刻動手去定位問題,而是先拉了一個臨時處理群,這樣做的原因是:
- 先將線上出故障了這件事情同步出去,要讓相關(guān)的人知道,像運維、測試、你的上級、產(chǎn)品等;
- 一定是先止損,優(yōu)先【線下去處理故障】,而不是【直接在線上處理故障】;
群拉完后,我簡單同步現(xiàn)象后,就開始分析了,首先想的第一點就是:
是不是因為做了線上變更導致的,比如有發(fā)版之類的。
從這個點切入去想的原因是源于自己處理線上故障的經(jīng)驗,大部分都是發(fā)版導致的,能回滾的優(yōu)先回滾,第一時間降低影響。因此我打開了發(fā)版日歷(技術(shù)團隊是有維護一個發(fā)版日歷的,記錄了每次發(fā)版或者變更的內(nèi)容),發(fā)現(xiàn)3月2號當天,在線上做了如下兩件事情:
- 部分服務接入了阿里云WAF,這個是因為安全原因,需要接入;
- 管理后臺對應的前后端服務,確實也發(fā)版了;
火速電話公司的安全專家,先臨時關(guān)閉WAF,但關(guān)閉后沒有用,訪問管理后臺還是一直出現(xiàn)503提示,沒辦法了,得立刻回滾當天上線的內(nèi)容,正當運維要操作回滾的時候,我反而制止了它。因為:
管理后臺突然又能訪問了。
😂,跟產(chǎn)品和業(yè)務方確認了一下,他們也反饋系統(tǒng)恢復了。好吧,這個也算一個好消息,畢竟可以給技術(shù)團隊多一些時間去定位問題。
系統(tǒng)臨時性恢復后,我這邊也就沒那么大的壓力和緊迫感了,靜下心來開始著手仔細分析,找出根因。
分析過程
是否有突增的流量過來
使用阿里云的SLS日志平臺,寫了個簡單的腳本,執(zhí)行后發(fā)現(xiàn),流量一直很平滑。雖然是管理后臺的服務,但是還是要先看看流量的,因為有可能有一些定時任務或者重量級業(yè)務操作,導致瘋狂的調(diào)用管理后臺服務。
是否是發(fā)版導致的?
由于發(fā)版的內(nèi)容還不少,很難一下子分析出是哪些代碼導致的,只能利用阿里的日志平臺以及監(jiān)控平臺,從故障發(fā)生的時間范圍里,尋找一些蛛絲馬跡。
首先是查看故障時間內(nèi),對應的后端服務有無返回狀態(tài)碼非200的,可以使用阿里的SLS日志平臺,寫個簡單命令查詢一下即可:
xxxx_app_id:yyyy not statusCode: 200 復制代碼上面的一些查詢字段,是可以在SLS上自己定義的。最終發(fā)現(xiàn)返回的狀態(tài)碼都是200的,這個就有點奇怪,但還是繼續(xù)看一下有無異常日志。
xxxx_app_id:yyyy and logLevel: ERROR 復制代碼發(fā)現(xiàn)也沒有,初步判斷,不是后端代碼上線導致的,便轉(zhuǎn)而開始用阿里云的監(jiān)控平臺觀察后端服務pod節(jié)點的運行情況,但也沒有什么收獲,pod既無重啟的情況,內(nèi)存、CPU usage也都正常,也沒有什么慢的請求。
當時就有點摸不著北了,由于那會也比較晚了,后臺管理系統(tǒng)也暫時沒有出現(xiàn)問題了,我就先回家了。而隔天又有其他重要緊急的事情要處理,我就忘記去跟這個事情了,一直到3月6號早上,又開始出現(xiàn)503問題了,持續(xù)時間是兩分鐘,然后就又自己恢復了。
這次我就把手頭上的事情先全部放下,全力跟進這個問題。經(jīng)過3月2號晚上的分析,感覺跟后端服務沒有關(guān)系,那會不會是前端的node服務有問題呢? 當然平時如果線上出故障,我很少認為會是前端問題,都是先從后端服務定位起。
但這次沒辦法,死馬當活馬醫(yī),于是便到阿里云上去看一下前端pod節(jié)點的運行情況,發(fā)現(xiàn)有重啟的情況,我感覺發(fā)現(xiàn)新大陸了,馬上去確定pod重啟時間,但是很遺憾,我沒權(quán)限看,就臨時去看一下這個pod的內(nèi)存波動情況,一般來說,pod有重啟的話,內(nèi)存會短暫釋放,果然,在故障期間,前端的pod的內(nèi)存占用有下降的趨勢,然后故障后的幾秒,內(nèi)存占用又恢復了日常水平。
于是便火急火燎的跑去找了一下運維:
把前端的xxx pod有重啟的情況,我懷疑管理后臺503問題,是這個原因?qū)е碌?#xff0c;你能不能把這個pod重啟前的日志發(fā)我一下。
當時運維回復說,重啟前的日志找不到了哦。當然,這句話我是不信的。就讓運維去查一下或者找阿里云的售后,看看怎么拿到pod重啟前的日志。果然,可以使用kubectl命令,找到日志:
kubectl describe pod xxxx-pro-vyyyyyyyy | grep 'State: ' -A 5
日志里有幾個信息:
- 一個是pod重啟前的代碼報錯日志;
- 一個是pod具體的重啟時間;
- 一個是Exit Code,這個code等于1,說明pod重啟,是服務自身的報錯導致的。
報錯日志如下:
TypeError [ERR_HTTP_INVALID_HEADER_VALUE]: Invalid value "undefined" for header "Content-Length"
到此,基本就清楚了,請求先經(jīng)過阿里WAF和阿里nginx-ingress后,由nginx-ingress轉(zhuǎn)發(fā)給前端的service,進而進入到pod,但是由于pod同一時間都在重啟,暫時無法提供服務,service這一層就不知道pod的狀態(tài),nginx-ingress自然也就無法知道service的狀態(tài),于是便返回了503。等重啟完畢后,就又正常提供服務,之所以偶發(fā)的出問題,原因就在這里。
于是便找了前端的開發(fā)leader去定位原因,最后他回復說,要改一個底層文件,兼容一下Content-Length為空的情況,改完后,簡單在在測試環(huán)境和預發(fā)布環(huán)境測試一下,過一下核心主流程,沒問題后,就上線了。
從3月9日上線到現(xiàn)在,暫時沒有發(fā)現(xiàn)503問題了。
那靈魂一問來了,這個底層文件,從2021年來一直都沒有改動過,也沒出過啥事,為啥最近才開始出問題呢? 答案是:
比較難查,不知道是哪些請求會沒有Content-Length,但肯定是發(fā)版導致的。
總結(jié)
以上是生活随笔為你收集整理的解决一个偶现的503 bug,花了俺不少时间的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chariot iperf使用_调用Ix
- 下一篇: ios16屏蔽系统更新