系統宕機,內存溢出等典型問題排查思路及工具使用

 
問題範圍:平臺典型後端問題,如宕機、服務響應慢、節點丟失、CPU高、內存高、數據庫響應慢等。分析這類問題雖然沒有固定套路,但是有大概方向。
工具範圍:平臺自帶服務質量監控、堆分析工具、線程分析工具、arthas、visualvm、zabbix監控等。分析內存問題(OOM、GC)首先要建立JVM內存知識結構。
以下以JDK8和CMS GC爲標準

問題

  宕機

    分析jvm crash文件
  • 檢查工作目錄(%AWS_HOME%/bin,優先檢查)或系統臨時目錄下,是否有hs_err_pid{pid}.log格式的文件
    1. 臨時目錄位置:windows:C:\Windows\Temp,macos: echo $TMPDIR,linux:/tmp
  • 分析方式1:用文本編輯器打開此文件
    1. 典型問題1:windows下,sla的的sigar組件兼容性不好。
    2. 典型問題2:OOM異常,需要繼續分析heap dump,見「OOM問題」
  • 分析方式2:用在線工具https://fastthread.io/打開,格式化展示,可以作爲協助。

  OOM

    平臺常遇到的2類OOM,可能引起宕機,也可能不會。
  • 最常見:java.lang.OutOfMemoryError: Java heap space
    1. 原因:堆空間已滿,且GC之後無法騰出更多空間
    2. 線索來源
      1. 日誌文件
      2. crash文件
      3. %AWS_HOME%/logs目錄下產生了hprof後綴的文件
    3. 確定問題
      1. 需分析heap dump文件,見「工具-MAT」章節
  • 其次:java.lang.OutOfMemoryError: Metaspace
    1. 原因:加載到內存中的class的數量或體積太大導致
    2. 增大aws_startup.sh的-XX:MetaspaceSize=1024m -XX:MaxMetaspaceSize=1024m爲2048m即可,一般情況下1024足夠,除非安裝的應用特別多

  集羣節點不可用/集羣節點丟失

  此類未造成OOM但服務不可用問題相對宕機來講,更難定位,因爲宕機後有明顯線索。
  • 線索來源
    1. 後臺切換節點切換不過去
    2. 集羣節點反覆丟失/加入
    3. 頁面提示xx節點不可用
    4. 或者提示:同步出錯,請重試
  • 原因
    1. 絕大部分原因是由於GC停頓時間過長導致,解決方式見「問題-服務響應慢-GC時間過長」章節
    2. 極少情況是網絡抖動導致
  • 確定問題
    1. 在系統響應慢時,執行命令導出heap dump,分析內存中有哪些對象導致GC慢
    2. 分析heap dump見「工具-MAT」章節

  服務響應慢

    觀察SLA >3秒的線程,如果:
  • 單個請求慢,查看堆棧確定問題原因
    1. 等待數據庫返回
      1. 優化SQL,添加索引等
      2. 如果是流程表/任務表數據量很大(千萬以上)可以考慮分庫分表(SAD應用)
    2. 其他如等待網絡返回,需要具體情況具體分析
  • 整個平臺響應慢
    1. 優先考慮大量對象進入內存導致或其他代碼漏洞導致GC時間過長
    2. 實時查看GC時間是否過長,見「工具-jstat」章節
    3. 統計查看GC時間是否過長
      1. 開啓jvm的GC參數,會在相應目錄下產生gc文件
      2. 用工具分析GC時間,見「工具-gc日誌分析」章節

  CPU使用率高

    需要安裝監控工具監控CPU使用情況,持續>80%時,就要分析是正常業務還是代碼Bug。
  • 正常情況:從SLA觀察併發線程數很多,且請求響應時間尚可,可以考慮增加CPU資源。
  • 異常情況1:從SLA觀察到的併發線程數並不多,但CPU持續高位運行。
    1. 關注>3秒的線程堆棧
    2. 用jvisualvm對cpu採樣分析,見「工具-jvisualvm」章節
  • 異常情況2:頻繁GC造成
    1. 可用jstat工具查看GC情況,見「工具-jstat」章節
    2. 此類情況需要分析是正常業務對象還是代碼漏洞,前者增大堆內存即可(-Xmx和-Xms),後者需要導出dump分析對象情況,見「工具-MAT」

  無法創建線程

  報錯java.lang.OutOfMemoryError: unable to create new native thread
  • 原因:創建線程太多,已超過操作系統能承載的最大數量。
    1. 線程池使用錯誤導致創建太多線程
    2. 慢請求導致線程持續累積(慢請求原因很多,可從sla >3秒的線程堆棧尋找線索)
    3. 系統壓力確實太大,需要增加CPU和內存配置
  • 分析:導出thread dump(命令:jstack -l pid),分析:見「工具-fastthread.io」

工具

  Memory Analyzer (MAT)

  • 關注點1(重點):Leak Suspects部分
    1. 大多數時候,是由於查詢大量數據庫數據進入內存導致,可能是平臺Bug,也可能是二開代碼。此部分如何在日常運維中預防,見「運維監控-數據庫」章節
  • 關注點2:對象直方圖,按照Retained Heap(該類對象hold住的內存大小)排序,可以分析對象是合理的cache還是bug產生的大量對象
  • 關注點3:線程情況,按照Retained Heap(該線程hold住的內存大小)排序,關注前幾個hold住大對象的線程
  • MAT能展示的信息非常多,可以以各種角度分析對象情況,甚至可以用OQL語句(類似SQL)過濾查詢每個對象的數量

  fastthread.io

  該網站主要用來分析線程情況,會以各種視角展示線程。也可以分析crash日誌(見「問題-宕機」部分)
  • 關注點1:總的線程數(1500以上就值得警惕,如果是>2000,基本可以斷定有問題)
    1. 線程絕對不是越多越好,尤其注意server.xml裏的maxClient配置,一般出廠默認的800就足夠大了。
  • 關注點2:線程分組後的線程數,某類線程過多,需要根據實際情況排查
  • 關注點3:相同堆棧的線程
  • 關注點4:死鎖。二開多線程編程較少,此類情況不常見。

  jstat

  使用jstat命令,可以分析內存各區域的變化情況以及GC的時間,如圖中可以得到一下信息
  • 年輕代和老年代均處於爆滿情況(99%和100%)
  • 單次GC停頓時間非常長,FGCT/FGC=11秒左右(一般500毫秒以下爲合理值)
 

  jvisualvm

  jvisualvm是windows或mac版jdk自帶的圖形分析工具
  • 可通過jmx或jstatd連接遠程服務器,參考jvisualvm監控遠程jvm的兩種連接方式對比
  • 查看CPU、堆和線程的概覽
  • 查看線程的實時運行情況
  • 可對CPU進行抽樣分析,找到消耗CPU的方法(可具體到線程和方法級別)
  • 可對內存進行抽樣分析,找到大對象

  GC日誌分析

  • 優先:https://gceasy.io/
    1. 重點關注GC停頓時間,集羣節點通信timeout時長3秒,GC超過這個時間就會節點丟失
  • 其次:客戶端軟件:GC Viewer

  日誌鏈路追蹤

    平臺的鏈路非常短,默認只有web -> app
  • 如果懷疑是某個web服務導致的問題,可以通過結合web日誌和app日誌的traceId判斷是否是同一請求
 

運維監控

系統交付客戶使用時,需要給客戶同步相關運維知識,尤其是監控和告警機制。隨着時間推移,數據庫數量增大、業務應用增多後,可能出現意想不到的問題。需要相應的監控巡檢和告警機制,提前對系統進行人工干預或者排查問題。
 

  IaaS資源

  • 需要對IaaS層面資源,如CPU使用率、CPU負載、內存、網絡、IO等進行監控和告警通知。
  • Web服務器、APP服務器、和數據庫服務器、甚至是網關均需要。

  服務質量監控(SLA)

  SLA是用同進程Java統計運行情況,當JVM運行壓力小時,可有效統計,運行壓力大時,可供參考。
  • 巡檢關注1:>3秒的線程,此處太慢輕則影響用戶體驗,嚴重累積則導致系統不可用/宕機。
    1. 點擊時間按鈕打開堆棧,分析慢的原因。可能是慢sql、請求外部接口、處理大量數據等。
    2. 線程卡住之後,只能重啓平臺解決,無法kill掉線程。(強行kill可能導致資源泄露或其他不可控問題,java已廢棄線程的stop方法)
  • 巡檢關注2:Top5線程,系統啓動以來最慢的5個線程,可能線程已經運行結束,所以無法查看堆棧,所以只能提供線索。
  • 巡檢關注3:SQL返回條數告警(6.4.3以後),默認>1W告警。返回行數太多時,容易造成GC停頓時間過長甚至是OOM錯誤。同數據庫返回條數監控,需要配合使用,區別:
    1. 優點:AWS平臺可以記錄下調用SQL的位置(有詳細堆棧)
    2. 缺點:一次性返回超出JVM heap承受的數據時,會造成JVM宕機,從而無法記錄該事故。

  Java

  JVM監控工具有多種,藍鯨或zabbix使用居多。
  • 巡檢關注1:heap使用率。app server默認在heap達到配置的75%時進行FullGC(受參數-XX:CMSInitiatingOccupancyFraction控制),如果heap使用率連續若干分鐘均處於75%以上運行,則需要導出heap dump進行分析,此時可能有內存泄露。
  • 巡檢關注2:GC時間,GC過慢會影響系統運行。

  數據庫

    數據庫監控工具有多種,藍鯨或zabbix使用居多,或者用自帶命令分析log文件,每家客戶的手段不太一樣。
  • 巡檢關注1:返回條數>1W的數據,思路同SLA中的SQL返回條數告警,需要配合使用,區別:
    1. 優點:不受Java服務器宕機影響,理論上可記錄所有事故SQL
    2. 缺點:只能記錄SQL,無法準確判斷AWS的調用代碼位置,需要根據經驗去排查平臺。
  • 巡檢關注2:慢SQL。此類SQL會影響用戶體驗,增大Java服務器併發壓力,嚴重的話會導致大量請求積累,從而導致宕機。(所以需要巡檢關注SLA的>3秒的線程)

結束語

  1. 對於系統性問題的思考、理解,以上只是拋磚引玉,需要不斷學習實踐總結。比如MAT的各種對象信息、zabbix的各種jvm監控指標含義等。
  2. 尋找解決方案時,強烈建議google,效率n倍加(可以用翻譯軟件)
  1. 平時解決問題時積攢的零散知識,感覺缺乏底層理解時,可以先記錄,然後找“系統性”學習的機會。(首推極客時間,其次慕課網
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章