CPU 飆升怎麼辦?

大话性能發表於2024-05-22

0 1
線上伺服器 CPU 飆升,如何定位到 Java 程式碼

解決這個問題的關鍵是要找到 Java 程式碼的位置。 下面分享一下排查思路,以 CentOS 為例,總結為 4 步。

第 1 步,使用 top 命令找到佔用 CPU 高的程序。

第 2 步,使用 ps –mp 命令找到程序下佔用 CPU 高的執行緒 ID。

第 3 步,使用 printf 命令將執行緒 ID 轉換成十六進位制數。

第 4 步,使用 jstack 命令輸出執行緒執行狀態的日誌資訊。

下面詳細介紹每一步的操作。

第 1 步,在使用 top 命令之後,可以看到一個列表,其中包含 PID(程序 ID)、USER(操作使用者)、CPU 佔用率、記憶體佔用率、TIME+(執行時間)、COMMAND(執行命令)等資訊。一般預設按 CPU 佔用率從上到下降序排列,如下圖所示。

我們找到 COMMAND 列是 java 的這一行,說明這個程式就是用 Java 編寫的。然後,用記事本記下這一行的 PID,也就是程序 ID。

第 2 步,使用 ps -mp 命令,輸出這個 PID 下面的執行緒執行情況列表,如下圖所示。

在這個列表中包含了幾個關鍵欄位,比如 CPU 佔用率、TID(執行緒 ID)、TIME(執行時間)等。在這個列表中找到 CPU 佔用最高的執行緒,記下 TID,也就是執行緒 ID。

前面記下的 TID 是一個十進位制數,不能直接使用,需要轉化為十六進位制數。

第 3 步,使用 printf 命令將 TID 轉換為十六進位制數,如下圖所示。

這樣就得到了真正佔用 CPU 過高的執行緒 ID。

第 4 步,使用 jstack 命令輸出執行緒的具體執行日誌,如下圖所示。

jstack 有 3 個引數,第 1 個引數是前面記下的 PID,之後加上 grep,緊跟著是轉成十六進位制數的 TID,最後加上 –A 和一個數字,這個數字表示輸出日誌的行數,至此就可以直接列印出具體的異常資訊了。如果日誌資訊比較多,異常內容比較複雜,則可以把這些異常資訊輸出到一個 txt 檔案中,慢慢分析。只需要在 jstack 命令的最後追加 txt 檔名就可以了。

jstack PID | grep TID -A60 >> error_log.txt

面試點評: 從這個問題來看,面試官主要考查求職者的實操能力,以及解決問題的思路。如果求職者沒有實操過,但是知道導致 CPU 飆升的原因,並說出解決思路,那麼透過面試是沒問題的。


0 2

生產環境伺服器變慢,如何診斷處理

生產環境伺服器變慢主要涉及 3 個維度:CPU 利用率、磁碟 I/O 效率、記憶體瓶頸。

1. CPU 利用率

CPU 利用率過高或者 CPU 利用率過低,都會影響程式的處理效率。CPU 利用率過高,說明當前伺服器要處理的指令比較多,當 CPU 忙不過來的時候,指令的執行效率自然就會下降,使用者的感受就是程式響應變慢了。

針對這個問題,我們可以使用 top 命令查詢當前系統中佔用 CPU 過高的程序,並定位到這個程序中比較活躍的執行緒。再透過 jstack 命令列印當前虛擬機器的執行緒快照,根據快照日誌排查問題程式碼。

如果 CPU 利用率過低,則說明程式資源使用不夠,可以增加執行緒數量提升程式效能。

2. 磁碟 I/O 效率

在程式執行過程中會直接或者間接涉及一些與磁碟 I/O 相關的操作,比如程式直接讀/寫磁碟或者程式依賴的第三方元件對磁碟進行持久化儲存,此時磁碟 I/O 效率就會對程式執行效率產生影響。

針對這種情況可以使用 iostat 命令檢視,如果磁碟負載較高,可以針對性地進行最佳化。比如,藉助快取系統,減少磁碟 I/O 次數;用順序寫替代隨機寫入,減少定址開銷;使用 mmap 替代 read/write,減少記憶體複製次數。 另外,磁碟 I/O 效率可以透過 CPU 與負載的非線性關係體現出來。當負載增大時,系統吞吐量不能有效增大,CPU 不能線性增長,則很可能是磁碟 I/O 出現阻塞。

3. 記憶體瓶頸

記憶體作為一塊臨時儲存資料的元件,所有 CPU 執行的指令都需要從記憶體中去讀/寫。記憶體的合理使用可以減少應用和磁碟的 I/O 頻率,減少網路 I/O 的頻率,極大地提升 I/O 效能。

JVM 對記憶體的合理分配,能夠避免頻繁的 YGC 和 FULL GC。 當記憶體使用率較高時,可以用 dump 命令查出 JVM 堆記憶體,用 MAT 工具進行分析,查出大物件或者佔用記憶體最多的物件,以及排查是否存在記憶體洩漏的問題。如果用 dump 命令查出的堆記憶體檔案正常,則可以考慮是堆外記憶體被大量使用導致出現問題,此時需要藉助作業系統的 pmap 命令查出程序的記憶體分配情況。如果 CPU 和記憶體使用率都很正常,那麼就需要進一步開啟 GC 日誌,分析使用者執行緒暫停的時間、各部分記憶體區域 GC 次數和時間等指標,這裡可以藉助 jstat 命令或視覺化工具 GCEasy 等。如果問題出在 GC 上,則考慮是不是記憶體不足,然後根據垃圾物件的特點進行引數調優,使用更適合的垃圾收集器,用 jstack 命令分析各個執行緒的狀態。如果問題比較隱蔽,則考慮是否開啟 JMX,使用 visualmv 等視覺化工具進行遠端監控與分析。

面試點評: 這個問題涉及的知識面比較多,如果只是站在求職者的角度來分析,則可以這樣回答。如果你沒有實際解決過類似問題,則可以說一下自己的思路,只要大體思路和方向是對的,那麼在遇到類似問題的時候,可以利用網路上的資料去逐步嘗試解決。

0 3

線上介面負載劇增,快扛不住了,你的首選方案是什麼

遇到這樣的問題,我們的第一反應應該是增加快取。 因為,增加快取是解決系統效能問題最快速、最高效的方案,它能夠快速提升系統的線性吞吐量,效果也最為明顯。這就相當於是用空間來換取時間。曾經有人說過,快取是解決效能問題的萬金油,哪裡存在效能瓶頸,就往哪裡加快取。 但是程式都已經上線了,增加快取還來得及嗎?因為在增加快取時需要改程式碼,所以,臨時解決方案就是增加節點。隨後,將程式緊急部署到新的節點上,在流量入口增加限流和分發。但是增加節點自然會增加成本,所以增加快取才是最優的解決方案。快取的設計思想在架構設計中十分常見。比如我們每天用的作業系統,不管是 Windows、Linux,還是 Mac OS 都有系統快取、使用者快取。磁碟有磁碟快取區、CPU 有 CPU 快取區。再比如,在我們常用的經典框架中,也經常使用到快取,Spring 有 IoC 快取,MyBatis 有一級快取、二級快取。在架構設計中,可以說快取無處不在。因此,當併發量過高扛不住的時候,可以優先採用快取來緩解負載壓力。比如將讀取頻繁的資料寫到快取中,將動態頁面靜態化。在加上快取之後,如果負載壓力依然過大,則再考慮增加限流策略,比如訊息佇列;如果在增加限流後還是壓力過大,則再考慮增加伺服器節點。

更多內容可以學習《測試工程師 Python 工具開發實戰》書籍《大話效能測試 JMeter 實戰》書籍

相關文章