性能指標有哪些

java領域佼佼者 發佈 2022-06-03T22:46:28.351745+00:00

1、響應時間(Response time)響應時間就是用戶感受軟體系統為其服務所耗費的時間,對於網站系統來說,響應時間就是從點擊了一個頁面計時開始,到這個頁面完全在瀏覽器里展現計時結束的這一段時間間隔,看起來很簡單,但其實在這段響應時間內,軟體系統在幕後經過了一系列的處理工作,貫

1、響應時間(Response time)

響應時間就是用戶感受軟體系統為其服務所耗費的時間,對於網站系統來說,響應時間就是從點擊了一個頁面計時開始,到這個頁面完全在瀏覽器里展現計時結束的這一段時間間隔,看起來很簡單,但其實在這段響應時間內,軟體系統在幕後經過了一系列的處理工作,貫穿了整個系統節點。根據「管轄區域」不同,響應時間可以細分為:

  1. 伺服器端響應時間,這個時間指的是伺服器完成交易請求執行的時間,不包括客戶端到伺服器端的反應(請求和耗費在網絡上的通信時間),這個伺服器端響應時間可以度量伺服器的處理能力。
  2. 網絡響應時間,這是網絡硬體傳輸交易請求和交易結果所耗費的時間。
  3. 客戶端響應時間,這是客戶端在構建請求和展現交易結果時所耗費的時間,對於普通的瘦客戶端 Web 應用來說,這個時間很短,通常可以忽略不計;但是對於胖客戶端 Web 應用來說,比如 Java applet、AJAX,由於客戶端內嵌了大量的邏輯處理,耗費的時間有可能很長,從而成為系統的瓶頸,這是要注意的一個地方。

那麼客戶感受的響應時間其實是等於 客戶端響應時間 + 伺服器端響應時間 + 網絡響應時間。細分的目的是為了方便定位性能瓶頸出現在哪個節點上。

2、吞吐量(Throughput)

吞吐量是我們常見的一個軟體性能指標,對於軟體系統來說,「吞」進去的是請求,「吐」出來的是結果,而吞吐量反映的就是軟體系統的「飯量」,也就是系統的處理能力,具體說來,就是指軟體系統在每單位時間內能處理多少個事務/請求/單位數據等。但它的定義比較靈活,在不同的場景下有不同的詮釋,比如資料庫的吞吐量指的是單位時間內,不同 sql 語句的執行數量;而網絡的吞吐量指的是單位時間內在網絡上傳輸的數據流量。吞吐量的大小由負載(如用戶的數量)或行為方式來決定。舉個例子,下載文件比瀏覽網頁需要更高的網絡吞吐量。

#資源使用率(Resource utilizatIOn)

常見的資源有:CPU占用率、內存使用率、磁碟I/O、網絡I/O。

3、點擊數(Hits per second)

點擊數是衡量 Web Server 處理能力的一個很有用的指標。需要明確的是:點擊數不是我們通常理解的用戶滑鼠點擊次數,而是按照客戶端向 Web Server 發起了多少次 http 請求計算的,一次滑鼠可能觸發多個 http 請求,這需要結合具體的 Web 系統實現來計算。

4、並發用戶數(Concurrent users)

並發用戶數用來度量伺服器並發容量和同步協調能力。在客戶端指一批用戶同時執行一個操作。並發數反映了軟體系統的並發處理能力,和吞吐量不同的是,它大多是占用套接字、句柄等作業系統資源。

另外,度量軟體系統的性能指標還有系統恢復時間等,其實凡是用戶有關資源和時間的要求都可以被視作性能指標,都可以作為軟體系統的度量,而性能測試就是為了驗證這些性能指標是否被滿足。

(二)如何發現性能瓶頸

在找性能瓶頸之前,我們要先對系統性能有一個概念

如何在不購買新硬體的條件下完成更多的工作?何時才真正需要添加硬體(更多的內存,更快的磁碟、 CPU以及網絡接口)?有時只需消除一些簡單的瓶頸即可解決許多性能問題——但是要實現它,你必須充分了解自己的計算機和網絡,從而找到真正的瓶頸所在。

說得直白一點,系統性能就是在儘可能減少投資的情況下,解決下面兩個事:

  1. Throughput:吞吐量。也就是每秒鐘可以處理的請求數,任務數。
  2. Response time:響應時間。也就是系統在處理一個請求或一個任務時的響應時間。

我們要做優化,就是為了讓吞吐量更大,讓響應時間更短,在二者之間達到平衡,滿足我們的業務要求。

所以,我們要發現性能瓶頸,其實就是找到影響吞吐量和響應時間的地方。

1、使用壓力測試工具發現性能瓶頸

網上的壓力測試工具有很多,這裡舉幾個實際工作中常用的

Java Melody

能夠在 QA 和實際運行生產環境監測 Java 或 Java EE 應用程式伺服器。並以圖表的形式顯示:Java 內存和 Java CPU 使用情況,用戶 Session 數量,JDBC 連接數,和 http 請求、sql 請求、jsp 頁面與業務接口方法(EJB3、Spring、Guice)的執行數量,平均執行時間,錯誤百分比等。圖表可以按天,周,月,年或自定義時間段查看。

2、Apache JMeter

Apache JMeter 是一個專門為運行和伺服器裝載測試而設計的、100% 的純 Java 桌面運行程序。原先它是為 Web/HTTP 測試而設計的,但是它已經擴展以支持各種各樣的測試模塊。它和用於 HTTP 和 SQL 資料庫(使用 JDBC)的模塊一起運送。它可以用來測試靜止資料庫或者活動資料庫中的伺服器的運行情況,可以用來模擬對伺服器或者網絡系統加以重負荷以測試它的抵抗力,或者用來分析不同負荷類型下的所有運行情況。它也提供了一個可替換的界面用來定製數據顯示,測試同步及測試的創建和執行。

3、Load Runner

LoadRunner,是一種預測系統行為和性能的負載測試工具。通過以模擬上千萬用戶實施並發負載及實時性能監測的方式來確認和查找問題,LoadRunner 能夠對整個企業架構進行測試。企業使用 LoadRunner 能最大限度地縮短測試時間,優化性能和加速應用系統的發布周期。 LoadRunner 可適用於各種體系架構的自動負載測試,能預測系統行為並評估系統性能。

發現瓶頸,怎麼辦?

先去作業系統,作業系統的報告。看看作業系統的 CPU 利用率,看看 內存使用率,看看 作業系統的 IO,還有 網絡的 IO,網絡連結數,等等。通過了解作業系統的性能,我們才知道性能的問題,比如:帶寬不夠,內存不夠,TCP 緩衝區不夠,等等,很多時候,不需要調整程序的,只需要調整一下硬體或作業系統的配置就可以了。說這些是為了提醒你,不要急著去修改你的代碼。

如果到了非要動代碼的地步,瓶頸這東西也可以根據 2:8 原則來說,20% 的代碼耗了你 80% 的性能,找到那 20% 的代碼,你就可以優化那 80% 的性能。所以,緊緊鎖定那不到 20% 的代碼。

(三)性能調優的常見手段

常見的網際網路架構中,一般都能看到 Spring + MyBatis + MySQL + Redis搭配的身影。一般來說,應用內部的接口都是直接調用的,所謂的面向接口編程,應用間的調用直接調或者通過類似 Dubbo 之類的服務框架來執行,數據格式往往採用 JSON,即統一也方便各數據間做轉換和取值,緩存一般使用 Redis 或 Memcached,存儲一些對象或 JSON 格式的字符串。對外提供的接口,一般都需要進行壓力測試,以便估算其性能,並為後續的調優提供指導方向,以下接口便是在壓測過程中出現的各種「奇怪現象」,所謂奇怪,指的是從表象上看與我們正常的邏輯思路不符,但其本質還是我們對壓力下程序的表現出來的特徵不熟悉,用慣用的知識結構試圖去解釋,這根本是行不通的。下文是我在一次全面壓測過程後對數據進行的分析匯總,其中的現象是很多壓測常見的,裡面的分析過程及改進措施我認為有很大的參考意義。具體內容如下:(部分接口為了安全我省略了其名稱,但不影響我們的分析,另外形如 1N3T 之類的表示的是 1 台 Nginx,3 台 TOMCAT,具體的 TPS 數值只是為了說明優化前後的比照,沒有實際意義)

1、名詞解釋

TPS

每秒鐘處理完的事務次數,一般 TPS 是對整個系統來講的。一個應用系統 1s 能完成多少事務處理,一個事務在分布式處理中,可能會對應多個請求,對于衡量單個接口服務的處理能力,用 QPS 比較多。

QPS

每秒鐘處理完請求的次數;注意這裡是處理完。具體是指發出請求到伺服器處理完成功返回結果。可以理解在 Server 中有個 Counter,每處理一個請求加 1,1 秒後 Counter = QPS。

RT

響應時間,處理一次請求所需要的平均處理時間

並發量

系統能同時處理的請求數

2、真實調優案例

a、接口:獲取列表

壓測現象:單台 TPS 700 多,應用 CPU 高負載

問題分析

舊框架,平均響應時間長,應用 CPU 高,程序內部有大量的 BEAN 到 MAP 到 JSON 之間的轉換,修改資料庫連接數後,TPS 沒有提升。

改進措施

重構系統,用 MyBatis 替代之前的 DAO 操作,減少 BEAN - MAP - JSON 之間的內部數據轉換,減少程序內部的無用操作。

改進效果

TPS 改進後能到 3000 左右,有較大提升,但壓測時應用 CPU 幾乎跑滿,還有改善空間。

壓測現象:資料庫資源利用率高

問題分析

單台應用,資料庫資源 CPU 都能到 50%,10 台 TOMCAT 在 1萬 並發下資料庫 CPU 跑滿,LOAD 值 700 多,但 DB 的 QPS 也不過 11554,並不算多,因此懷疑是 SQL 執行耗費了 CPU,可能是某條 SQL 沒有按索引查找或者索引失效。

改進措施

查看 SQL 文件發現如下 sql:select count(1) from orders where order_status_id !=40 ,將其改為 select order_id from orders 然後通過程序把 order_status_id != 40 的過濾掉。通過 list.size() 來獲取。order_status_id 即使加了索引,由於是 != 比較,所以不會去按索引查找,導致 CPU 高

改進效果

相同環境下(1台 Nginx,10 台 Tomcat,1000 並發),TPS 由 3000 變成 3727,略有增長,但是 DB 的 CPU 明顯下降,變為 30%,效果明顯

壓測現象:1N15T,TPS 4552;10N15T,TPS 9608

問題分析

後端都是 15 台 Tomcat,前端 1 台 Nginx 時 TPS 為 4552,通過 LVS 掛 10 台 Nginx 時為 9608,增長不明顯,其 Nginx 和 Tomcat 都壓力不大,集群結果不合理,懷疑是 Nginx 轉發配置的問題;

改進措施

未進一步改進:可能是需要調整 Nginx 的參數,之前發現過 Nginx 不同的配置對後端集群環境的 TPS 影響很大

改進效果

b、接口:信息查詢

壓測現象:單台 TPS 2000 多,應用 CPU 高,DB 的 QPS 15000 左右

問題分析

舊框架,程序內部有很多 Bean - Map - Json 相互的轉換

改進措施

刪除冗餘代碼、更換連接池包,使用 MyBatis

改進效果

TPS 由 2000 多增長為 8000 多,DB 的 QPS 為 9000 左右,優化後壓測應用的 CPU 占用高,幾乎跑滿。

壓測現象:資料庫無壓力,應用增加多台後 TPS 不變

問題分析

1N1T 和 1N10T 的 TPS 一樣,都為 5000,增大並發時錯誤數增多,應用 CPU 耗費 70%,DB 無壓力,Nginx 單台通過 ss –s 發現埠占滿,即 Nginx 到 Tomcat 之間轉發的連接埠 time-wait 狀態 6 萬多。Nginx 存在瓶頸。

改進措施

調優 Nginx 參數,將短連接改為長連接

改進效果

1N3T 的 TPS 能到 17376,Tomat 的 CPU 壓力 84%,DB 的 QPS 18000,CPU 69%,應用的資源基本使用到量。

c、接口:獲取詳情

壓測現象:單台應用 TPS 2600,10 台 Tomcat 才 3700

問題分析

增加應用伺服器,TPS 增長不明顯,且 Nginx、Tomcat、DB 的負載都不高,說明伺服器本身不是瓶頸,考慮是不是網絡的問題,通過監控網卡包流量發現網絡數據跑滿,因為此接口會有大量數據的輸出,因此瓶頸在網絡上。另外,測試過程中發現 Redis 有報錯,Redis 伺服器是虛機,可能服務能力有限。

改進措施

開啟 Tomcat 的 gzip 壓縮。

改進效果

同等並發下(1 台 Nginx,10 台 Tomcat,1000 並發),TPS 由 3727 增長到 10022,增長了近 3 倍,效果顯著。

壓測現象:1N10T 集群下 Nginx 參數調優對 TPS 提升效果明顯

問題分析

經過 Tomcat 的啟用 gzip 後,1N10T 下 TPS 為 10022,需進一步提升。

改進措施

優化 Nginx:

  • Nginx 日誌關閉
  • Nginx 進程數量 worker,由 24 改為 16
  • nginx keepalive 數量由 256 改為 2048

改進效果

TPS 由 10022 提升為 13270。

壓測現象:1N5T 和 1N10T 的 TPS 相差不大

問題分析

1N10T 的 TPS 為 1萬3千多,1N5T 的 TPS 為 1萬2千多,相差不大,應用的 Tomcat 資源利用沒滿,CPU 為 65%,DB 的 QPS 已經到 2萬多了,單台伺服器 DB 基本上到量了,因此再增加應用也沒效果,只會導致響應的時間變長。

改進措施

單台 DB 已經無法改進了,要不提升伺服器硬體,要不讀寫分離。

改進效果

d、接口:促銷

壓測現象:通過 Redis 存取數據,TPS 才 1000 多,CPU 有壓力

問題分析

此接口通過 Redis 取數據,TPS 不高才 1000 多,但 CPU 占用了 80%,說明程序內部有大量序列化反序列化的操作,可能是 JSON 序列化的問題。

改進措施

將 net.sf.json 改成 alibaba 的 fastjson

改進效果

同等並發條件下 TPS 由 1000 多提升為 5000 多,提高了近5倍。

壓測現象:參數多時 TPS 下降明顯

問題分析

此接口根據參數從 Redis 中獲取數據,每個參數與 Redis 交互一次,當一組參數時 TPS 5133,五組參數時 TPS 1169,多次交互影響了處理性能。

改進措施

將從 Redis 獲取數據的 get 改為 mget,減少交互次數。

改進效果

五組參數時 1N3T 壓測 TPS 9707,據此估算即使是單台 Tomcat,TPS 也能有三四千,性能比單次 get 的調用方式提升了 3,4 倍。

壓測現象:1N3T TPS 1萬多,在增大 Tomcat 可能 TPS 增長不會明顯

問題分析

此處說的是可能,因為 Nginx 伺服器的 CPU 雖然不高,但 QPS 已經 8000 多,此時應該是 Nginx 的伺服器網絡流量成為了瓶頸。(只是猜測)

改進措施

可以增加多台 Nginx 負載,前端加 LVS

e、接口:追蹤接口

壓測現象:1N10T 的 TPS 低於 1N3T 的 TPS

問題分析

1N3T 在 2000 並發下 TPS 為 9849,此時 DB 的 QPS 為 90000,CPU 80%,將 Tomcat 增到 10 台,5000 並發下,TPS 為 7813,DB 的 QPS 為 19000,CPU 75%,load 1,說明壓力增大情況下 DB 的壓力反而下來了,注意到 Nginx 伺服器的網卡流量達到 885M,說明是壓力過大情況下,網絡滿了,發生丟包,導致 DB 端壓力反而下來了。

改進措施

注意壓測情況下部分接口由於數據量傳輸較大,會出現網絡瓶頸。

f、接口:回填接口

壓測現象:TPS 不到 500,DB 的 QPS 3500

問題分析

雖然缺少應用的 CPU 及 DB 的 CPU 利用率數據,較低的 TPS 應該是應用的瓶頸,且需要關注是不是 DB 在處理查詢的時候緩慢。

改進措施

  1. 連接池由 DBCP 改為 HIKAR
  2. 減少了日誌列印輸出
  3. SQL 優化,將部分條件過濾改為在 Java 代碼中執行

改進效果

TPS 由不到 500 增長為 1300 多

g、接口:券查詢

壓測現象:集群結果與單台應用結果相比不合理

問題分析

查看是否存在瓶頸資源,可以看到 5 台 Tomcat 集群下,TPS 為 9952,但 DB 的 QPS 為 5-6 萬,CPU 利用率為 37%,說明對資料庫進行了大量的主鍵或索引查詢,一般單台 DB 的 QPS 也就 4萬左右,再增加應用的集群數量,對 TPS 也不會有太大影響。

改進措施

可以考慮分庫

h、接口:推薦

壓測現象:Nginx 長短連接差異

問題分析

18 台 Nginx,2 Tomcat 時 TPS 8100,此時應用伺服器的埠數滿,一般來說,Nginx 短連接在高並發下容易導致埠占滿的問題。

改進措施

將 Nginx 改為長連接

改進效果

TPS 增長為 10733,TPS 穩定,起伏減少,但是 CPU 耗盡。說明 CPU 打滿了,此時如果還要優化就的進行代碼調優了。

i、接口:查詢

壓測現象:18N20T 的 TPS 才 6842

問題分析

18 台 Nginx,20 台 Tomcat,TPS 才 6842,此時應用 CPU 利用率 85%,說明 CPU 存在瓶頸,但檢查此接口並未做大計算量的工作,有可能是日誌的級別問題,CPU 在頻繁的打日誌。

改進措施

將日誌級別由 DEBUG 級改為 INFO 級

改進效果

同等環境 TPS 由 6842 增長為 23592


如果本文對你有幫助,別忘記給我個3連 ,點讚,轉發,評論,

咱們下期見!學習更多JAVA知識與技巧,關注與私信博主(666)

關鍵字: