天天看點

性能測試監控名額及分析調優

作者:京東雲開發者

一、哪些因素會成為系統的瓶頸?

1、CPU,如果存在大量的計算,他們會長時間不間斷的占用CPU資源,導緻其他資源無法争奪到CPU而響應緩慢,進而帶來系統性能問題,例如頻繁的FullGC,以及多線程造成的上下文頻繁的切換,都會導緻CPU繁忙,一般情況下CPU使用率<75%比較合适。

2、記憶體,Java記憶體一般是通過jvm記憶體進行配置設定的,主要是用jvm中堆記憶體來存儲Java建立的對象。記憶體的讀寫速度非常快,但是記憶體空間又是有限的,當記憶體空間被占滿,對象無法回收時,就會導緻記憶體溢出或記憶體洩漏。

3、磁盤I/O,磁盤的存儲空間要比記憶體存儲空間大很多,但是磁盤的讀寫速度比記憶體慢,雖然現在引入SSD固态硬碟,但是還是無法跟記憶體速度相比。

4、網絡,帶寬的大小,會對傳輸資料有很大影響,當并發量增加時,網絡很容易就會成為瓶頸。

5、異常,Java程式,抛出異常,要對異常進行捕獲,這個過程要消耗性能,如果在高并發的情況下,持續進行異常處理,系統的性能會受影響。

6、資料庫,資料庫的操作一般涉及磁盤I/O的讀寫,大量的資料庫讀寫操作,會導緻磁盤I/O性能瓶頸,進而導緻資料庫操作延遲。

7、當在并發程式設計的時候,經常會用多線程操作同一個資源,這個時候為了保證資料的原子性,就要使用到鎖,鎖的使用會帶來上下文切換,進而帶來性能開銷,在JDK1.6之後新增了偏向鎖、自旋鎖、輕量級鎖、鎖粗化、鎖消除。

二、哪些名額做為衡量系統的性能

1、RT響應時間,包括如下

1.1 資料庫響應時間,即資料庫操作的時間

1.2 服務端響應時間,服務端包括Nginx分發的請求所消耗的時間及服務端程式執行所消耗的時間。

1.3 網絡響應時間,網絡傳輸,網絡硬體需要對傳輸的請求進行解析所消耗的時間

1.4 用戶端響應時間,一般Web、App用戶端,消耗時間可以忽略不計,但是如果用戶端存在大量的邏輯處理,消耗的時間有可能就會變長。

2、TPS吞吐量

2.1 磁盤吞吐量

IOPS(Input/Output Per Second)每秒的輸入輸出量,這種是機關時間内系統能處理的I/O請求數量,I/O請求通常為讀或寫資料操作請求,關注随機讀寫性能,适用于随機讀寫頻繁的應用,如小檔案存儲,郵件伺服器。

資料吞吐量,這種是機關時間可以傳輸的資料量,對于大量順序讀寫頻繁的應用,傳輸大量連續資料,例如視訊編輯。

2.2 網絡吞吐量

指網絡傳輸時沒有丢幀的情況下,裝置能夠接受的最大資料速率。網絡吞吐量不僅跟帶寬有關系,還跟CPU處理能力、網卡、防火牆、以及I/O等緊密聯系,吞吐量的大小由網卡的處理能力、内部程式算法以及帶寬大小決定。

3、資源使用率

3.1 CPU使用率,首先可以先了解CPU的基本資訊,包括實體CPU的個數、單個CPU的核數,然後可以通過指令檢視使用率,vmstat、mpstat、top

3.2 記憶體使用率,free -m、vmstat、top

3.3 磁盤I/O, iostat、 iotop、

3.4 網絡I/O,netstat、ifconfig、tcpstat、

三、性能測試注意的問題

1、我們在做性能測試的時候,系統的運作會越來越快,後面的通路速度比我們第一次通路的速度快了好幾倍,這是因為Java語言編譯的順序是,.java檔案先編譯為.class檔案,然後通過解釋器将.class的位元組碼轉換成本地機器碼後,才能運作。為了節約記憶體和執行效率,代碼最初被執行時,解釋器會率先解釋執行這段代碼。随着代碼被執行的次數增多,虛拟機發現某個方法或代碼運作的特别頻繁,就被認定為熱點代碼(Hot Spot Code)。為了提高熱點代碼的執行效率,在運作時虛拟機将會通過即時編譯器(JIT)把這些代碼編譯成為本地平台相關的機器碼,然後儲存在記憶體中,之後每次運作代碼時,直接從記憶體中擷取。這樣就會導緻第一次系統運作慢,後面通路的速度快幾倍。

2、在做性能測試的時候,每次測試處理的資料集都是一樣的,但是結果卻有差異,這是因為測試時,伴随着很多不穩定因素,比如機器其他程序的影響、網絡波動以及每個階段JVM垃圾回收的不同等。我們可以通過多次測試,将測試結果求平均,隻要保證平均值在合理範圍之内,并且波動不是很大,這種情況,性能測試就算通過。

四、定位性能問題的時候,可以使用自下而上的政策分析排查

當我們進行壓測之後,我們會輸出一份性能測試報告,其中包括,RT、TPS、TP99,被壓伺服器的CPU、記憶體、I/O,以及JVM的GC頻率。通過這些名額可以發現性能瓶頸。我們可以采用自下而上的方式進行分析。

1、首先從作業系統層面,檢視系統的CPU、記憶體、I/O、網絡的使用率是否異常,再通過指令查找異常日志,最後通過日志分析,找到導緻瓶頸的問原因。

2、還可以從Java應用的JVM層面,檢視JVM的垃圾回收頻率以及記憶體配置設定情況是否存在異常,分析垃圾回收日志,找到導緻瓶頸的原因。

3、如果系統和JVM層面都沒有出現異常情況,然後可以從應用服務業務層檢視是否存在性能瓶頸,例如,Java程式設計問題,讀寫資料庫瓶頸等。

五、優化性能問題的時候,可以使用自上而下的政策進行優化

整體的調優順序,我們可以從業務調優到程式設計調優,最後再到系統調優

1、應用層調優

首先是優化代碼,代碼問題往往會因為消耗系統資源而暴漏出來,例如代碼導緻記憶體溢出,使JVM記憶體用完,而發生頻繁的FullGC,導緻CPU偏高。

其次是優化設計,主要是優化業務層和中間件層代碼,例如可以采用代理模式,放在頻繁調用的建立對象的場景裡,共享一個建立對象,減少建立對象的消耗。

再次是優化算法,選擇合适的算法降低時間複雜度。

2、中間件調優

MySQL調優

1)、表結構與索引優化。

主要是對資料庫設計、表結構設計以及索引設定次元進行的優化,設計表結構的時候,考慮資料庫的水準與垂直的拓展能力,提前規劃好将來資料量、讀寫量的增長,規劃好分庫分表方案。對字段選擇合适的資料類型,優先選用較小的資料結構。

2)、SQL語句優化。

主要是對SQL語句進行的優化,使用explain來檢視執行計劃,來檢視是否使用了索引,使用了哪些索引。也可以使用Profile指令分析語句執行過程中各個分步的耗時。

3)、MySQL參數優化。

主要是對MySQL服務的配置進行優化,例如連接配接數的管理,對索引緩存、查詢緩存、排序緩存等各種緩存大小進行優化

4)、硬體及系統配置。

對硬體裝置和作業系統設定進行優化,例如調整作業系統參數、禁用swap、增加記憶體、更新固态硬碟。

3、系統調優

首先是作業系統調優,Linux操作的核心參數設定可以進行調優,已達到提供高性能的目的。

其次,JVM調優,設定合理的JVM記憶體空間,以及垃圾回收算法來提高性能,例如,如果業務邏輯會建立大對象,我們就可以設定,将大的對象直接放到老年代中,這樣可以減少年輕代頻發發生YongGC,減少CPU的占用時間。

4、調優的政策

首先是時間換取空間,有的時候系統對查詢速度要求不高,對存儲空間要求較高,這個時候我們可以考慮用時間換取空間。

其次是空間換取時間,用存儲空間提升通路速度,典型的就是MySQL的分庫分表政策,MySQL表單資料存儲千萬以上的時候,讀寫性能就會下降,這個時候我們可以将資料進行拆分,以達到查詢的時候,每個表的資料是少量的,以達到提升性能的目的。

5、兜底政策

系統調優後,仍然還會存在性能問題,這個時候我們需要有兜底政策,

首先是限流,對系統的入口設定最大通路限制,同時采取斷熔措施,傳回沒有成功的請求。

其次是橫向擴容,當通路量超過某一個門檻值時,系統可以自動橫向增加服務。

作者:京東健康 牛金亮

來源:京東雲開發者社群