一次線上死迴圈的排查

蕭亦全發表於2019-07-02

1、問題發現

      Prometheus報警某服務的一個節點 Old GC過多,需要排查。

2、檢視GC日誌

      使用tail -f gc.log命令檢視異常節點的GC日誌,從日誌可以看出Young GC過於頻繁,竟然在1s內有9次Young GC:
一次線上死迴圈的排查
      使用tail -f gc.log命令檢視正常節點的GC日誌,從日誌可以看出,正常節點,很久才進行一次Young GC:
一次線上死迴圈的排查
      兩個節點的JVM引數配置是完全一樣的,並且負載均衡策略使用的是Ribbon預設的輪詢策略,也就是說,兩個節點能夠接受到的請求是均衡的,不存在一個節點比另一個階段負載大的情況。
      使用jstat命令檢視異常節點的Young GC頻率,發現確實存在異常:
一次線上死迴圈的排查

3、使用jps命令找出該應用程式的pid,再使用top -Hp pid命令檢視該程式下佔用CPU最多的執行緒id:

一次線上死迴圈的排查

4、將查到的執行緒id 9182,使用printf "%x\n" 9182命令,轉換為16進位制:

一次線上死迴圈的排查

5、使用jstack 9088 | grep 23de -A 30命令檢視堆疊資訊(多次檢視):

      第一次:
一次線上死迴圈的排查
      第二次:
一次線上死迴圈的排查
      該執行緒一直處於Running狀態,並且兩次檢視中發現,堆疊中有共同的方法呼叫,懷疑問題可能發生在RedPackUtilV3.java:169處,需要檢視業務同學程式碼。

6、檢視業務同學程式碼

一次線上死迴圈的排查
發現極有可能是while迴圈中break條件一直沒成立,導致了死迴圈,最後就請業務同學自己檢查程式碼邏輯了。

相關文章