問題排查:線上環境CPU飆到300%多。。

背景

線上一臺後端服務所在機器CPU飆到300%多。。這個過程並不是一下子就完成的,而是過幾個小時就來一次,奇了怪了。

解決思路

  1. 保護現場;
  2. 查看日誌;
  3. 查看進程:top -c
  4. 查看Java線程棧:jstack -l 32508 > jstack.32508.log
  5. 查看Java堆內存:jmap -dump:live,format=b,file=32508-1.bin 32508
  6. 工具分析:MAT:https://www.eclipse.org/mat/downloads.php
  7. 解決問題

以下進行一一說明:

  • 保護現場;

如果條件允許,要保留一個服務進行問題分析。

  • 查看日誌;

肯定要看日誌的,有沒有報錯信息等。

  • 查看進程:top -c

查看對資源消耗嚴重的進程列表。

  • 查看Java線程棧:jstack -l 32508 > jstack.32508.log
    在這裏插入圖片描述
    可以看到解密相關線程阻塞。。

  • 查看Java堆內存:jmap -dump:live,format=b,file=32508-1.bin 32508

2020-05-08-CPU-Map.jpg

對線上環境,間隔時間,連續三次dump出堆內存信息。從這幾個文件大小也可以看出,隨着時間推移,內存佔用越來越大,請看下一步。

  • 工具分析:MAT:https://www.eclipse.org/mat/downloads.php

依次打開上一步導出的三個bin文件:

在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述

可以發現,類javax.crypto.JceSecurity的實例佔據的堆內存持續增加,最終導致OOM,線程阻塞,CPU飆升。。

  • 解決問題

JceSecurity類中有個Map,verificationResults是一個靜態對象,無法被JVM回收。

2020-05-08-CPU-Jce1.jpg

2020-05-08-CPU-Jce2.jpg

問題代碼:

Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
原來是每次用戶登錄,都有一個`BouncyCastleProvider`對象被放到`IdentityHashMap`中,而這個Map(static)又無法被回收。。
解決方法就是將`BouncyCastleProvider`作爲單例,而不是每次解密時都new一個新對象。
private static org.bouncycastle.jce.provider.BouncyCastleProvider bouncyCastleProvider = null;
public static synchronized org.bouncycastle.jce.provider.BouncyCastleProvider getInstance() {
    if (bouncyCastleProvider == null) {
        bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
    }
    return bouncyCastleProvider;
}

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", getInstance());

本地環境,問題復現

進行本地測試,用到的工具:

  • Java虛擬機可視化監控:JConsole, JavaVisualVM(JDK自帶)
  • 壓力測試:JMeter(http://jmeter.apache.org/download_jmeter.cgi)

測試步驟如下:

1. 本地啓動後的服務;
2. `JavaVisualVM` 監聽服務的進程;
3. `JMeter`壓測解密相關接口;

在這裏插入圖片描述

內存從開始的幾百M到多線程壓測時的1G+,然後有一部分內存GC無法回收,最終堆內存佔用保持在1G左右。。

jmap -dump:live,format=b,file=11428.bin 11428導出的bin文件,加載至MAT進行分析。

2020-05-08-CPU-Leak.jpg

2020-05-08-CPU-OOM.jpg

可以看到與線上環境的問題一樣,問題復現完成。問題不重要,這裏僅提供解決問題的一個思路。


If you have any questions or any bugs are found, please feel free to contact me.

Your comments and suggestions are welcome!

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