天天看點

一覽性能瓶頸分析方法

分析性能瓶頸需要了解系統部署架構,知道瓶頸可能會發生在哪些節點上,并熟悉檢視各個節點名額資料的方法。

一、系統部署架構

一個典型的系統部署架構,有硬體伺服器,包括應用系統所在的伺服器、資料庫伺服器、負載均衡器等,還有Web伺服器、App應用伺服器、資料庫等軟體,性能瓶頸會散布在各個節點上。可以通過檢視其性能名額來分析這些節點是否出現性能瓶頸。此外,有些項目使用的第三方工作流、ETL等工具,通常也會提供性能名額。

二、監控

一個好的監控系統可以快速獲得節點的性能資訊。當系統被部署在雲端(例如阿裡雲)時,雲服務商也會提供比較成熟的監控能力,監控對象包括CPU平均使用率、可用記憶體、平均讀寫磁盤數、網絡輸入輸出位元組數、資料庫連接配接數、隊列深度等名額。當我們需要自己建構監控系統時,可以使用Prometheus、Grafana、Spring Boot Actuator和AlertManager建構微服務監控系統。最後,如果沒有監控系統,也可以手工去各節點收集需要的名額資訊,當然效率相對較低。

除了監控系統提供的資訊外,伺服器端的日志檔案也是分析性能瓶頸的重要依據,我們可以使用特殊關鍵字如OutOfMemory、SQLException、Error等進行搜尋。

三、分析過程

首先要排除壓測工具自己導緻的瓶頸。例如用JMeter做壓測,要确定單台機器允許啟動的最大線程數。一般會使用兩台配置相當的機器,一台部署JMeter,另一台部署Mock伺服器(伺服器傳回簡單的字元串即可),通過不斷調整JMeter的并發線程,找到允許的最大并發數。

如何幫助JMeter提高并發線程數呢?

  • 修改JMeter啟動檔案,增加虛拟機允許的記憶體使用量。
  • 用指令行模式啟動壓測,而不是使用其界面模式。JMeter的界面模式隻用于腳本的調試。
  • 正式壓測時移除JMeter的監聽器以提高性能。

如果需要更大的壓測請求量,可以用多機并發壓測(主從機模式),或者使用雲壓測平台。壓測過程中,會碰到系統響應時間長、壓測請求數上不去等情況,可以檢視各個節點的性能名額去發現其性能瓶頸,主要關注如下名額。

  1. CPU

通常伺服器的CPU占用率在75%以内是正常的,如果長期在90%以上,就需要将其看作性能瓶頸進行排查。CPU占用率高,原因通常如下。

  • 代碼問題。例如遞歸調用(當退出機制設計不合理時)、死循環、并發運作了大量線程。
  • 實體記憶體不足。作業系統會使用虛拟記憶體,造成過多的頁交換而引發CPU使用率高。
  • 大量磁盤I/O操作。它會讓系統頻繁中斷和切換,引發CPU占用率高。
  • 執行計算密集型任務。
  • 硬體損壞或出現入侵。

如果發現伺服器CPU占用率很高,先檢查請求線程數、記憶體、I/O使用情況以及JVM記憶體垃圾回收頻率等。多核CPU的伺服器,有時會出現總體CPU占用率不高,但某個核的占用率達到100%的情況(同一個線程會一直占用一個核),就會導緻系統響應緩慢。

在Linux系統中,可以使用top指令檢視程序的CPU負載,用vmstat指令檢視系統的CPU負載。

vmstat -n 1表示每秒重新整理一次CPU負載資訊,其傳回資料的常見含義如下。

  • r:運作中的隊列數,如果該數值長期大于CPU數,則出現CPU硬體的瓶頸。
  • us:使用者程序執行時間百分比,簡單來說,該數值高通常是由寫的程式引起的。
  • sy:核心系統程序執行時間百分比。
  • wa:磁盤I/O等待時間百分比,數值較高時表明I/O等待較為嚴重。
  • id:空閑時間百分比。

在壓測過程中,吞吐量較低、伺服器CPU占用不高,可能是業務處理的線程出現了等待狀态(例如鎖等待)導緻的,或者本應并發處理的任務被同步處理,減緩了處理速度。

吞吐量較低、伺服器CPU占用率很高,則可能是因為服務端在執行CPU高消耗的業務,例如複雜算法、壓縮/解壓縮、序列化/反序列化等。

吞吐量高、伺服器CPU占用率也高,則表明服務端處理能力強。如果需要降低CPU占用率,可以對過多的請求做限流處理。

  1. 記憶體

随着壓測請求增加,通常記憶體使用量也會增加,我們需要注意當壓測請求量消失一段時間後,記憶體有沒有恢複到壓測前的水準,如果沒有恢複,則系統可能存在記憶體洩漏。

Java虛拟機中,如果代碼建立了大量生命周期長的臨時對象,會使記憶體使用率一直居高不下,高記憶體使用率會頻繁觸發垃圾回收機制,垃圾回收執行時會降低系統的響應能力。

  1. 磁盤I/O

當磁盤成為性能瓶頸時,一般會出現磁盤I/O繁忙,導緻執行程式在I/O處等待。在Linux中,使用top指令檢視wa資料,判斷CPU是否長時間等待I/O。

用iostat -x指令檢視磁盤工作時間,傳回資料中的%util是磁盤讀寫操作的百分比時間,如果超過70%就說明磁盤比較繁忙了,傳回的await資料是平均每次磁盤讀寫的等待時間。

用iostat -d可以檢視磁盤的吞吐量資訊,傳回資料中的tps是每秒的讀寫次數,其他資料是磁盤的讀寫資料量統計。

  1. 網絡帶寬

一般在區域網路做壓測,網絡帶寬很少出現瓶頸。當傳輸大資料量,帶寬同時被其他應用占用以及有網絡限速等情況時,則帶寬可能成為性能瓶頸。理論上,1000Mbit/s網卡的傳輸速度是125MB/s,100Mbit/s網卡是12.5MB/s,實際的傳輸速度會受如交換機、網卡等配套裝置影響。在Linux伺服器上檢視網絡流量的工具很多,有vnStat、NetHogs、iftop等。

  1. 資料庫伺服器

以MySQL資料庫為例。

  • 檢查伺服器的硬體資源CPU、記憶體、磁盤等是否出現了瓶頸。
  • 開啟慢查詢日志,使用set global slow_query_log = 1記錄下超過指定時間的SQL語句,定位分析性能瓶頸。
  • 使用set global innodb_print_all_deadlocks = 1記錄死鎖日志。
  • 使用show variables like '%max_connection%';檢視資料庫設定的最大連接配接數,使用show status like 'Threads%';檢視資料庫的目前連接配接數。
  1. Web應用伺服器
  1. App應用伺服器
  • JVM的記憶體使用率統計資訊,包括目前堆大小、目前空閑堆等;
  • JMS消息隊列的連接配接統計資料,包括目前連接配接數、最大連接配接數等;
  • JDBC連接配接池的相關統計資料;
  • 目前應用伺服器的線程活動資訊,包括執行線程數、空閑線程數、吞吐量、完成的請求數等。

繼續閱讀