記一次線上排障——內存爆滿、頻繁GC、CPU 100%

一. 本文簡介

1.1 線上故事 —— 線上內存爆滿、頻繁GC、CPU 100% ,節點頻繁重啓

1.2 故障定位排查

1.3 經驗反思(看官若是着急,可直接看這裏)

二. 線上故事與排查

2.1 線上故事

    與以往發佈項目流程一樣,上午項目A開始由運維灰度發佈(a,b集羣8節點)。部署日誌如下:

部署流程看上去一切正常,節點部署與驗證均通過。看樣子,這次上線應該沒啥問題,可以安心喫個午飯,下午再新業務驗證。然而......

在b集羣還在繼續部署,流量全部打在已部署完成的a集羣時(即a集羣4個節點承擔了100%流量),線上告警觸發,a集羣開始有節點自動重啓。趕緊去看項目的日誌明細。一場在線定位故障的大幕拉開。

2.2 線上故障排查

  日誌查看系統graylog顯示最近5分鐘,error 日誌不到10條,大部分error內容爲獲取數據庫連接異常:

說實話,當時看到這個異常時,心裏還不是很慌(好歹不是業務代碼異常,要是出現NPE,那要挨板子~)。然而......

當看到這種數據庫連接獲取不到時,心想着,部署趕上業務高峯期啦? 走你,去grafana看項目指標監控去。

節點http請求統計圖:

業務接口調用topN 統計圖

看上去,11點後部署的時候,業務請求量確實不算小,難道是剛巧a,b集羣灰度部署的時候,一半的4個節點沒抗住100%流量,有請求在獲取數據庫連接這裏堆積並超時引發error,並進一步觸發了節點健康檢查未通過,導致節點重啓?

隨着健康的節點數漸漸上升,在未見到其他error日誌的情況下,本以爲一切虛驚一場。但隨後健康節點數一直未恢復到初始值8,伴隨着重啓,數量一直在上下波動。此時,除了收到告警,相關技術工作羣裏,開始有依賴我們的服務負責人,在詢問我們的服務是不是跪了!緊接着,客戶端業務線也反饋頁面加載緩慢!事情開始變的緊急了(生產無小事,是我們反應慢了,尤其系統重啓)。這時候,由於第一步定位問題太粗糙了,未能拍板是發佈的代碼引起的問題,所以在節點頻繁重啓且影響上下游服務的時候,我們走了擴容節點而非回滾版本的動作(注意,這一動作有很大的爭議,值得商榷)。但是,擴容了一倍來到了16個節點,重啓現象並未解決,只是減小了對上下游的影響。這時候,心裏預感應該是新上的代碼有問題了。在放棄新上業務回滾後,重啓現象消失。

繼續看grafana監控,異常指標跳入眼簾。

JVM 統計指標

Container 指標

上面JVM和CPU 的監控指標,內容概括下就是:內存突然爆滿,GC執行變得頻繁,GC耗時來到可怕的秒級,cpu也直接幹滿了。 這些,纔是本次節點重啓的原因(打臉啊,一開始居然沒看這些指標)。

那,什麼引起了這些現象?哪裏的代碼突然吃了那麼多內存?進而引起了GC 和CPU 瘋狂幹活??

這個時候,review代碼,有點力不從心,新上的代碼多,涉及開發人員也多。根本上,dump分析纔是王道。這裏不討論如何獲取和分析dump,使用當前部署環境運維能支持的手段。我們這裏使用的是 perfma 集成化dump收集分析軟件。在運維準備perfma環境以及後面學習使用的同時,負責跟進排查的人也在梳理上線後的監控指標與相關日誌,並check核心代碼。

後面我們懷疑了String拼接的兩個方法,但一推算,哪怕調用一次申請1k的內存資源,1000qps也才1m,短時間內不可能導致內存驟升。應該是創建了什麼大對象。

可能真是當局者迷,亦或者上線觸發告警自亂了陣腳。最終,在數據庫慢查日誌這裏,找到了苗頭

查詢耗時慢不可怕,可怕的是返回的記錄數達到了400K+ ... 這就很恐怖了,一條查詢就可以輕鬆喫掉幾十上百兆的內存。再一定位代碼,是本次新加的查詢代碼。至此,真相基本浮出水面。不多久,那邊的perfma也有了結果:

一個線程就喫掉了440m內存,再觀察具體實例屬性,對應的實體ToutiaoExposureRecord,沒跑了,就是那個慢查。

後面查了下生產的數據庫:

業務代碼那裏,未對生產的idfa 爲0000000 做兼容考慮,遂查詢引發了後續事故。

代碼修正後,部署上線,監控指標一切正常了。

三. 經驗反思

3.1 生產出現故障,不能掉以親心但也不要慌亂!穩住!

3.2 降低故障影響面,降低損失!寧可放棄上線新功能,萬不可宕機影響現有業務功能!

3.3 排障注意章法流程,不要東一榔頭西一棒子。應用運行log,系統內存、線程、cpu監控等利用起來。以及,注意數據庫慢查!!!

 

思考:在本次案例中,部署上線後,出現節點重啓,可用健康節點不足一半的情況下,已經嚴重影響其他業務功能了。此時,節點重啓原因還未找到,是選擇擴容暫時保系統還是選擇回滾版本呢?擴容相當於給了更多節點重啓的緩衝時間,以數量換時間;回滾相當於認爲問題出在新版本的代碼上,但回滾部署,根據這裏灰度發佈的流量調整規則(見第一張圖),會將100%的流量打到一半的節點上,假設此時承受流量的那一半節點已經奄奄一息了,那服務估計就被打爆了!這種場景,也是需要根據實際情況認真考慮斟酌的!

 

評論區歡迎討論!覺得有用點個贊再走吧。感謝!!!

 

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