記一次JAVA進程導致Kubernetes節點CPU飆高的排查與解決


一、發現問題

在一次系統上線后,我們發現某幾個節點在長時間運行后會出現CPU持續飆升的問題,導致的結果就是Kubernetes集群的這個節點會把所在的Pod進行驅逐(調度);如果調度到同樣問題的節點上,也會出現Pod一直起不來的問題。我們嘗試了殺死Pod后手動調度的辦法(label),當然也可以排除調度節點。但是在一段時間后還會復現,我們通過監控系統也排查了這段時間的流量情況,但應該和CPU持續占用沒有關聯,這時我們意識到這可能是程序的問題。

二、排查問題

定位Pod

這里使用kubectl top pods 命令確定CPU占用最高的pods都是哪些。

kubectl -n app top pods

因為問題已解決,以上圖片只是舉個例子。

排查工具

Arthas

我們這邊使用了阿里的Arthas ,它是Alibaba開源的Java診斷工具。當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:

這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?

我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?

遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?

線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!

是否有一個全局視角來查看系統的運行狀況?

有什么辦法可以監控到JVM的實時運行狀態?

怎么快速定位應用的熱點,生成火焰圖?

排查問題

定位到有問題的Pod后,使用kubectl exec進入Pod容器內部:

kubectl -n app exec -it 49a89b2f-73c6-40ac-b6de-c6d0e47ace64-5d489d9c48qwc7t  -- /bin/bash

在容器中下載Arthas

wget https://arthas.gitee.io/arthas-boot.jar

由於我們打包鏡像中只有一個服務,所以一個Pod中也只有一個進程; 這里 1 是指PID。

java -jar arthas-boot.jar 1

執行進程看板 dashboard:

[arthas@1]$ dashboard

這里上半區顯示了線程內容,我們可以看到哪個線程ID的對應情況:

比如從上面得到了線程ID,使用如下命令進入線程,如ID 12262:

[arthas@1]$ thread -n 12262

打印出線程日志:

[arthas@1]$ thread -n 12262
"com.alibaba.nacos.client.Worker.addr-bj-internal.edas.aliyun.com-7362814c-538b-4c26-aa07-1fd47765a145" Id=20190 cpuUsage=7% TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@d30d0a4e (in native)
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@d30d0a4e
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:813)

三、解決問題

經過了排查定位到了問題,最后經過社區和阿里雲伙伴的協助,發現了這個是Nacos 2.0.0.RELEASE的一個BUG。我們對Nacos客戶端版本進行了升級,經過測試后,問題解決了。也加深了對Kubernetes集群調試的能力 [加油]。

<dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      <version>2.0.1.RELEASE</version>
</dependency>

四、最后

通過社區和阿里雲的幫助,問題成功解決。在工具方面,阿里提供的Arthas,真的是線上環境調試神器!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM