『StabilityGuide』| 10+位阿里技術專家共同發起穩定性知識庫開源項目

簡介: 我們穿過山和大海,也見過人山人海。我們見過各類故障,也排過千雷萬險。這一次,不如我們一起,開啓穩定性的探索之旅。讓無法解決的問題少一點點,讓世界的確定性多一點點。無論是前端業務的開發者,還是後端架構的開發者,都會遇到業務穩定性的難題。

我們穿過山和大海,也見過人山人海。
我們見過各類故障,也排過千雷萬險。
這一次,不如我們一起,開啓穩定性的探索之旅。
讓無法解決的問題少一點點,讓世界的確定性多一點點。

無論是前端業務的開發者,還是後端架構的開發者,都會遇到業務穩定性的難題。但穩定性的話題涉及之廣、之深,很難通過一兩篇文章道清原委。因此,我們集結了多位阿里技術工程師,他們來自性能壓測、故障演練、JVM、應用容器、服務框架、流量調度、監控、診斷等不同的技術領域,以更結構化的方式來打造穩定性領域的知識庫,該知識庫的目錄將分爲:

  • 事前規範:代碼規約、變更管控、性能壓測、故障演練、風險預案、限流降級、業務隔離;
  • 事中“止血”:監控、告警、異常巡檢、流量調度;
  • 事後診斷:系統診斷、JVM診斷、組件診斷、在線診斷、鏈路追蹤、Root cause;

但我們也深知,僅憑阿里自身的業務場景和技術積累,很難滿足各行業不同業務場景下對穩定性知識和經驗獲取的需求,因此,我們將以開源的方式進行共建,歡迎您將自己或所在企業在穩定性方面的實踐分享給更多的人,讓無法解決的問題少一點,讓世界的確定性多一點:

  • 開源項目名稱:StabilityGuide
  • 參與方式:
  1. 提 issue:將您遇到的穩定性難題詳細的描述出來;
  2. 寫文章:申領目錄中的某個主題,分享您或所在企業在穩定性方面的實踐;
  3. 其他:您認爲對『StabilityGuide』的建設有幫助的建議;
  • 項目地址,點擊這裏
  • 釘釘交流羣:23179349

歡迎在文末,寫下你的留言,隨機抽3位,送出紀念衫套裝( Polo 衫 & T恤,共計兩件)。

以下是來自『StabilityGuide』的第一篇文章:《系統穩定性——OutOfMemoryError 常見原因及解決方法》

當 JVM 內存嚴重不足時,就會拋出 java.lang.OutOfMemoryError 錯誤。本文總結了常見的 OOM 原因及其解決方法,如下圖所示。如有遺漏或錯誤,歡迎補充指正。

如果對 JVM 內存模型和垃圾回收機制不熟悉,推薦閱讀 《咱們從頭到尾說一次 Java 垃圾回收》

Java heap space

當堆內存(Heap Space)沒有足夠空間存放新創建的對象時,就會拋出 java.lang.OutOfMemoryError: Java heap space 錯誤(根據實際生產經驗,可以對程序日誌中的 OutOfMemoryError 配置關鍵字告警,一經發現,立即處理)。

原因分析

Java heap space 錯誤產生的常見原因可以分爲以下幾類:

  • 請求創建一個超大對象,通常是一個大數組。
  • 超出預期的訪問量/數據量,通常是上游系統請求流量飆升,常見於各類促銷/秒殺活動,可以結合業務流量指標排查是否有尖狀峯值。
  • 過度使用終結器(Finalizer),該對象沒有立即被 GC。
  • 內存泄漏(Memory Leak),大量對象引用沒有釋放,JVM 無法對其自動回收,常見於使用了 File 等資源沒有回收。

解決方案

針對大部分情況,通常只需要通過 -Xmx 參數調高 JVM 堆內存空間即可。如果仍然沒有解決,可以參考以下情況做進一步處理:

  • 如果是超大對象,可以檢查其合理性,比如是否一次性查詢了數據庫全部結果,而沒有做結果數限制。
  • 如果是業務峯值壓力,可以考慮添加機器資源,或者做限流降級。
  • 如果是內存泄漏,需要找到持有的對象,修改代碼設計,比如關閉沒有釋放的連接。

GC overhead limit exceeded

當 Java 進程花費 98% 以上的時間執行 GC,但只恢復了不到 2% 的內存,且該動作連續重複了 5 次,就會拋出 java.lang.OutOfMemoryError:GC overhead limit exceeded 錯誤。簡單地說,就是應用程序已經基本耗盡了所有可用內存, GC 也無法回收。

此類問題的原因與解決方案跟 Java heap space 非常類似,可以參考上文。

Permgen space

該錯誤表示永久代(Permanent Generation)已用滿,通常是因爲加載的 class 數目太多或體積太大。

原因分析

永久代存儲對象主要包括以下幾類:

  • 加載/緩存到內存中的 class 定義,包括類的名稱,字段,方法和字節碼;
  • 常量池;
  • 對象數組/類型數組所關聯的 class;
  • JIT 編譯器優化後的 class 信息。

PermGen 的使用量與加載到內存的 class 的數量/大小正相關。

解決方案

根據 Permgen space 報錯的時機,可以採用不同的解決方案,如下所示:

  • 程序啓動報錯,修改 -XX:MaxPermSize 啓動參數,調大永久代空間。
  • 應用重新部署時報錯,很可能是沒有應用沒有重啓,導致加載了多份 class 信息,只需重啓 JVM 即可解決。
  • 運行時報錯,應用程序可能會動態創建大量 class,而這些 class 的生命週期很短暫,但是 JVM 默認不會卸載 class,可以設置 -XX:+CMSClassUnloadingEnabled 和 -XX:+UseConcMarkSweepGC 這兩個參數允許 JVM 卸載 class。

如果上述方法無法解決,可以通過 jmap 命令 dump 內存對象 jmap -dump:format=b,file=dump.hprof ,然後利用 Eclipse MAT 功能逐一分析開銷最大的 classloader 和重複 class。

Metaspace

JDK 1.8 使用 Metaspace 替換了永久代(Permanent Generation),該錯誤表示 Metaspace 已被用滿,通常是因爲加載的 class 數目太多或體積太大。

此類問題的原因與解決方法跟 Permgen space 非常類似,可以參考上文。需要特別注意的是調整 Metaspace 空間大小的啓動參數爲 -XX:MaxMetaspaceSize。

想看完整文章內容:點擊這裏

原文出處:阿里雲大學開發者社區

作者信息:夏明,GitHub ID @StabilityMan,花名涯海,阿里雲 ARMS & EagleEye 技術專家,2016 年加入阿里巴巴,一直從事鏈路追蹤和 APM 監控診斷領域的相關工作。

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