最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于Java?CPU或內存使用率過高問題定位

 更新時間:2024年10月31日 16:25:13   作者:大腦補丁  
Spring?cloud微服務廣泛應用后,服務的監(jiān)控和運維壓力也與日俱增,經常有服務出現CPU或者內存使用率過高的告警,那么遇到這樣的問題我們該如何排查呢?我們可以借助哪些工具來定位問題呢?本文將介紹一下遇到此類問題的解決思路和方法

一.常見的性能問題優(yōu)化的經驗分享

1.通過應用日志定位思路

對于業(yè)務體量不大,QPS不高的服務來說,一般出現性能問題還是很好定位的,比如通過Prometheus等監(jiān)控平臺出現CPU或內存使用率過高的時間點,看一下這個時間點附近的應用日志,一般就可以看出其內存溢出的地方了,偶爾報錯的地方也并非就是引發(fā)性能問題的地方,因為報錯的地方只是壓垮駱駝的最后一根稻草,在此報錯點之前的地方有出現耗費性能的操作導致的。

有時候監(jiān)控趨勢圖顯示CPU彪生,但其實是因為OOM引發(fā)的,要清晰的定位這些問題,這就得再借助下其他工具了,后文再介紹。

2.常見的性能問題

我們發(fā)現了日志報錯點后,第一點就要去思考有沒有往內存中加載大量數據的操作,比如Excel導出一次性加載大量數據而不采用分頁的、一次加載大量Redis緩存的、一次Select查詢大量Mysql數據的地方。

這些都是及其容易引發(fā)內存溢出的地方,也是很多剛工作的同學經常犯的錯誤,他們在開發(fā)環(huán)境數據量少時不會暴露此類問題,但是一旦發(fā)布生產環(huán)境,單表數據量到百萬數量級,此類問題就會出現,所以自己或問問同事有沒有寫過類似的操作或接口,從而快速定位。

以上都是憑借經驗判斷,如果開發(fā)者資歷尚淺或者問題隱藏較深,我們就需要借助一些工具來定位問題了。

二.CPU利用率過高問題定位

如果發(fā)現CPU利用率過高,比如達到了90%-100%時,我們可以直接登陸應用服務器,通過以下步驟定位問題:

1.查看占用CPU高的線程

命令:top

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND\
4380 root      20   0 9415956 2.350g  26772 S  90.3 41.4 426:14.30 java\
2083 root      20   0 1141656   9460   7044 S   0.7  0.2 130:19.20 Asiainfocwexam\
2038 root      20   0  495668   5880   4776 S   0.3  0.1 524:46.15 Asiainfocwmonit\
2093 root      20   0 1377548  10244   8324 S   0.3  0.2 514:56.84 Asiainfocwsvrd\
6708 root      20   0   27520   3236   2460 S   0.3  0.1   0:00.15 sshd\
21114 root      20   0  729064  18340   6856 S   0.3  0.3  39:46.81 bkmonitorbeat\
1 root      20   0   41284   2860   1940 S   0.0  0.0   0:15.97 systemd

我們可以看出第一個進程PID:4380的CPU占用率過高,他就是我們的java服務,這里PID指的是進程,我們需要根據進程號,找到其占用CPU的線程。

命令:top -Hp 4380

注:

命令中H大寫,p小寫

  • top:在終端實時顯示系統性能數據的命令。
  • -H:該選項用于顯示所有線程的信息而不是僅顯示總體的信息。
  • -p 4380:該選項指定要監(jiān)視的進程的PID。在這里,4380是一個占位符,你可能會替換為實際的進程PID。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4558 root 20 0 9415956 2.333g 26772 S 92.9 41.1 160:56.84 java
4389 root 20 0 9415956 2.333g 26772 S 0.7 41.1 11:17.82 VM Thread
4473 root 20 0 9415956 2.333g 26772 S 0.7 41.1 4:38.15 redisson-netty-
4480 root 20 0 9415956 2.333g 26772 S 0.7 41.1 3:19.37 redisson-netty-

我們可以看到PID:4558的線程CPU使用率較高。

打印出問題線程的堆棧信息:

命令:printf '%x\n' 4558

將線程號轉為16進制顯示,用于在堆棧中定位線程。

注:

  • printf:是一個格式化輸出命令。
  • '%x\n':是格式控制字符串,表示將后面的參數按十六進制格式輸出,并在末尾添加換行符。
  • 4558:是要格式化輸出的整數。
[root]# printf ‘%x\n' 4558
11ce
命令 :jstack 4380|grep -A 100 11ce

通過jstack打印進程4380的堆棧信息,并只過濾出線程11ce的堆棧信息

命令含義:使用 jstack 來打印指定 Java 進程(PID為4380)的線程堆棧信息,然后使用 grep 過濾輸出,查找包含特定字符串 “11ce” 的行,并打印該行及其后續(xù)100行的內容。

注:

  • jstack 4380:使用 jstack 命令獲取 Java 進程 4380 的線程堆棧信息。
  • |:管道符,將 jstack 的輸出傳遞給下一個命令。
  • grep -A 200 11ce:使用 grep 過濾包含字符串 “11ce” 的行,同時打印每個匹配行的后續(xù)100行內容(包括匹配行本身)。

"org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1" #130 prio=5 os_prio=0 tid=0x00007f922eccd800 nid=0x11ce runnable [0x00007f91c80be000]
   java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
    at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
    at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
    at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
    - locked <0x0000000088383dc0> (a sun.nio.ch.Util$3)
    - locked <0x0000000088383db0> (a java.util.Collections$UnmodifiableSet)
    - locked <0x0000000088383d68> (a sun.nio.ch.EPollSelectorImpl)
    at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
    at org.apache.kafka.common.network.Selector.select(Selector.java:869)
    at org.apache.kafka.common.network.Selector.poll(Selector.java:465)
    at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:563)
    at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:265)
    at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:236)
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1292)
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1233)
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1206)

其中第一行中 nid=0x11ce,此處就是我們上面16進制線程號:11ce。所以此條堆棧對應的代碼行數,即為耗費CPU比較高的線程對應的代碼(上面堆棧僅為示例)。

三.內存利用率過高問題定位

1.內存過高代碼定位

內存過高和CPU過高一樣,都可以用上述方法定位,在下方%MEM列,即表示內存占用率,找出對應的PID,重復上面操作即可定位。

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND\
4380 root      20   0 9415956 2.350g  26772 S  10.2 91.4 426:14.30 java\

2.設置java啟動參數出現OOM自動打印堆棧

在服務器上建立好路徑,比如:/usr/local/app/logs,然后當服務發(fā)生OutOfMemoryError(OOM)內存溢出時,會自動打印堆棧信息到dump.hprof文件中,那時我們只需要分析此文件即可定位問題。

nohup java -XX:HeapDumpPath=/usr/local/app/logs/dump.hprof -XX:+HeapDumpOnOutOfMemoryError-jar /usr/local/app/test-web.jar  --spring.profiles.active=pro >/dev/null 2>&1 &

3.分析堆文件

在jdk安裝目錄下,jdk1.8.0_60\bin下,有jvisualvm.exe工具,打開這個工具,點擊文件->裝入->文件類型選擇hprof->選擇dump.hprof。

如下圖:

如果有OOM會顯示在概覽中,并且堆棧信息也打印了。

特別提醒:

OutOfMemoryError(OOM)的堆棧信息通常只顯示了導致內存不足的最終操作,而不一定反映了問題的根本原因。

OOM 堆棧信息中的最上層可能只是觸發(fā)了 Java 虛擬機報告內存不足的點,而不一定是導致內存不足的真正原因。

即此工具分析結果只是壓死駱駝的最后一根稻草,并不一定是導致內存溢出的原因,所以有時你還需要找到壓死駱駝的那塊大石頭,而不要只盯著這跟稻草優(yōu)化,比如有時候會顯示垃圾回收GC線程占用內存過高,但GC可不是導致OOM的根因。

大多數情況下,jvisualvm定位到的問題就是OOM的原因,但不全是,所以你要明白原因。

四.使用阿里巴巴Arthas診斷工具

1.Arthas能做什么?

Arthas有很多強大功能,本文只針對CPU和內存使用率過高的性能問題進行講解,其他用法參考《官方文檔》拓展閱讀吧。

2.下載Arthas

如果服務器可以連接互聯網,可以直接使用下面的命令下載,如果不能聯網,可以下載jar包后上傳到服務器。

curl -O https://arthas.aliyun.com/arthas-boot.jar

3.啟動Arthas

java -jar arthas-boot.jar

啟動時,需要手動選擇要監(jiān)控的java程序,如果只有一個,就輸入“1”,如果多個,輸入對應的序號數字即可,

如圖:

4.定位占用資源多的線程堆棧

使用命令打印出占用CPU的線程堆棧,即可定位問題,然后就具體情況具體分析了,每個人遇到的問題都是不一樣的,這里只教學下排除問題的方法。

以下是幾個常用的命令:

①.查詢最忙的3個線程,采樣5000毫秒內的堆棧信息:

thread -n 3 -i 5000

5000毫秒為采樣時間,如果不加-i 5000,那么默認是采樣200毫秒,采樣時間過短的話往往不太準確,因為采樣本身也會占用CPU性能,所以可以適當延長一下

②.查詢當前阻塞其他線程的線程:

thread -b

如果有堵塞的線程會打印出來,如果沒有則不會打印出結果。

比如一些kafka消費類的線程,會一直處于堵塞狀態(tài),這種其實也是正常的,并不是有堵塞的線程,就要去解決優(yōu)化。

我們要看看那些不應該長時間堵塞的線程,為啥出現了堵塞。

注:thread命令使用參考《官方文檔-thread命令》

③.查看JVM信息,下面三個命令都可以:

jvm
sysprop
sysenv

如果忙碌線程中,長時間出現GC,那就開啟GC日志,

XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log

看看是否出現了Full GC,Full GC日志示例:

2024-01-04T12:34:56.789-0500: [Full GC (System.gc()) [PSYoungGen: 0K->0K(5120K)] [ParOldGen: 4096K->4096K(10240K)] 4096K->4096K(15360K), [Metaspace: 1234K->1234K(8192K)], 0.0123456 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

如果出現了Full GC,那就用上文提到的jvisualvm.exe分析堆文件,找出占用內存大的對象,并優(yōu)化。

總結

本文介紹了通過系統日志、java JDK工具、JVM參數、linux系統命令、Arthas診斷工具等方法,定位和解決線上CPU使用率過高、內存使用率過高的方法,大家可以根據自己的環(huán)境靈活搭配使用上述方法,解決性能問題。

排查性能問題需要不斷的積累經驗的過程,新手可能感到無從下手,結合本文提到的工具,多嘗試、多總結,遇到性能問題不要僥幸,敬畏墨菲定律,不要想著重啟下就能解決,重啟大 法好,但不能提升你解決問題的能力。所以出現偶發(fā)的性能問題一定要及時去定位,不然就像定時炸彈一樣,在你下班時間引爆。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java打印高質量日志的10條方法詳解

    Java打印高質量日志的10條方法詳解

    你以為打日志是小事,也許正是這種輕視,讓你在凌晨三點被生產事故電話吵醒,一個優(yōu)秀的工程師和普通碼農的區(qū)別,往往體現在那些看似微不足道的細節(jié)上,下面我們就來看看如何打印高質量日志吧
    2025-06-06
  • 使用java的注解(用在java類的方法上的注解)方法

    使用java的注解(用在java類的方法上的注解)方法

    這篇文章主要介紹了使用java的注解(用在java類的方法上的注解)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • SpringBoot項目中使用Jasypt實現配置文件敏感信息加密

    SpringBoot項目中使用Jasypt實現配置文件敏感信息加密

    這篇文章主要介紹了如何使用Jasypt庫對SpringBoot項目中的敏感信息進行加密和解密,首先,生成加密密文,然后在SpringBoot配置文件中集成Jasypt,實現自動加密和解密,最后,強調了加密密鑰的安全配置,需要的朋友可以參考下
    2026-05-05
  • 關于Springboot中JSCH的使用及說明

    關于Springboot中JSCH的使用及說明

    這篇文章主要介紹了關于Springboot中JSCH的使用及說明,具有很好的參考價值,希望對大家有所幫助。
    2022-09-09
  • 實例講述Java IO文件復制

    實例講述Java IO文件復制

    本篇文章通過實例給大家詳細講述Java IO文件復制的相關知識點,需要的讀者們學習下吧。
    2018-02-02
  • SpringBoot JPA sort多屬性排序實例

    SpringBoot JPA sort多屬性排序實例

    這篇文章主要介紹了SpringBoot JPA sort多屬性排序實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Idea?編譯并運行?Spark?3.1.1?源碼的方法

    Idea?編譯并運行?Spark?3.1.1?源碼的方法

    這篇文章主要介紹了Idea?編譯并運行?Spark?3.1.1源碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • spring security中的csrf防御原理(跨域請求偽造)

    spring security中的csrf防御原理(跨域請求偽造)

    這篇文章主要介紹了spring security中的csrf防御機制原理解析(跨域請求偽造),本文通過實例代碼詳解的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • springboot中l(wèi)ogback日志配置的詳細說明

    springboot中l(wèi)ogback日志配置的詳細說明

    Logback 是一個高效、靈活的日志記錄工具,支持多種日志格式和輸出目標(如控制臺、文件等),通過配置 logback-spring.xml 文件,可以自定義日志的輸出方式和格式,下面給大家介紹springboot中l(wèi)ogback日志配置的詳細說明,感興趣的朋友一起看看吧
    2025-05-05
  • HashMap每次擴容為什么是2倍

    HashMap每次擴容為什么是2倍

    當HashMap在初始化沒有指定容量的情況下,首次添加元素時,數組的容量為16;當超出閾值,數組容量為擴容為之前的2倍,為什么HashMap每次擴容都是之前的2倍?下面就介紹一下
    2024-11-11

最新評論

黑河市| 兴仁县| 广汉市| 格尔木市| 曲水县| 大悟县| 铁岭县| 台湾省| 荥经县| 淮南市| 平山县| 新田县| 肇源县| 贵州省| 正镶白旗| 大竹县| 固安县| 綦江县| 汉沽区| 丰城市| 孙吴县| 汉寿县| 禄丰县| 大丰市| 佛冈县| 新竹县| 调兵山市| 上饶县| 清涧县| 东乌珠穆沁旗| 枝江市| 年辖:市辖区| 如东县| 东乡县| 潍坊市| 临邑县| 平果县| 南丹县| 崇阳县| 临清市| 慈溪市|