記一次單個服務將cpu佔滿的問題排查

一、發生故障

今天發現服務查詢一直卡住,就看了一下服務器:

圖片描述

當時就愣住了就這一個服務就把CPU佔滿了,再看了下端口號:

圖片描述

出現了大量的CLOSE_WAIT。看到這裏我就只有一個想法:程序代碼有問題或者是配置的問題

二、排查

爲此我先重啓了服務並加上參數用jconsole查看服務狀況:
-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=10000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

再打印GC日誌:
-verbose:gc
-Xloggc:/usr/app/ydjAgent/gc_log
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps

啓動參數太長了我又把它添加到環境變量裏:
vim /etc/profile

export JAVA_OPTS='-Xms1024m -Xmx4096m -Djava.rmi.server.hostname=120.0.0.1 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -verbose:gc -Xloggc:/usr/app/ydjAgent/gc_log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps'

根據jconsole概覽和GC日誌可以看的出,是因爲系統頻繁進行GC導致的:

圖片描述

圖片描述

一般情況下,young gc頻繁是正常的,full gc如果非常頻繁,一般情況下有問題的就是接口查詢中的集合的數據,存起來了,一直沒刪除,導致gc沒有及時回收。

然後將堆信息dump下來後用Eclipse memory analyze分析了一下,發現char[]數組和byte[]數組佔了大部分內存。

綜上分析後查明,因爲業務需要統計一個月內的所有訂單中的商品以及品牌排行,因爲原有表的設計的主鍵id是UUID,服務在啓動的時候只給了最大4G內存,即使是隻查詢訂單id,都佔了很大一部分空間,更別說後面查詢出來的訂單信息會佔用更大的內存空間,而因爲這樣,數據庫的壓力和應用的壓力也會很大,應用一直處於FULL GC狀態,把cpu佔滿。

三、解決辦法

因爲該應用和數據庫是在同一個服務器上,所以就先把應用部署到另一個服務器上然後用nginx通過內網將請求轉發,把內存設置8G,緩解原來服務器的CPU壓力,即便如此,在數據訪問的時候還是對數據庫造成了很大的壓力。因爲我代碼寫的太爛了哈哈。。事發之後先向老闆做了彙報,老闆表示理解。。給我時間去重新設計原有的架構。。。不說了寫代碼去。。。

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