如何做性能測試

轉(zhuǎn)自http://blog.csdn.net/liweisnake/article/details/51683090
性能優(yōu)化的常見概念
吞吐量(TPS, QPS):簡單來說就是每秒鐘完成的事務(wù)數(shù)或者查詢數(shù)。通常吞吐量大表明系統(tǒng)單位時間能處理的請求數(shù)越多,所以通常希望TPS越高越好
響應(yīng)時間:即從請求發(fā)出去到收到系統(tǒng)返回的時間。響應(yīng)時間一般不取平均值,而是要去掉不穩(wěn)定的值之后再取均值,比如常用的90%響應(yīng)時間,指的就是去掉了10%不穩(wěn)定的響應(yīng)時間之后,剩下90%的穩(wěn)定的響應(yīng)時間的均值。從聚類的觀點看,其實就是去掉離群點。
錯誤率:即錯誤請求數(shù)與總請求數(shù)之比。隨著壓力增加,有可能出現(xiàn)處理請求處理不過來的情況,這時錯誤數(shù)會不斷增加。
三者有極大的關(guān)聯(lián),任何孤立的數(shù)據(jù)都不能說明問題。典型的關(guān)系是,吞吐量增加時,響應(yīng)延遲有可能增加,錯誤率也有可能增加。因此,單拿出一個10w的TPS并不能說明問題。

性能調(diào)優(yōu)的思路
一般情況,調(diào)優(yōu)需要有個前提條件,即無論是用線上的真實流水還是線下的壓力測試讓問題擴(kuò)大化,明顯化。
根據(jù)這些比較明顯的現(xiàn)象去初判問題,收集證據(jù)去驗證初判結(jié)果成立,然后分析現(xiàn)象產(chǎn)生的原因,并嘗試解決問題。

1.性能摸底測試
對于新上的系統(tǒng)或者是有過較大代碼改動的系統(tǒng)來說,做一次摸底測試還是很有必要的。一般來說,期望摸底的測試是一次對單機(jī)的壓力測試。壓力測試可以幫你大概搞清楚系統(tǒng)的極限TPS是多少,在壓力上來時有沒有暴露一些錯誤或者問題,系統(tǒng)大致的資源占用情況是什么,系統(tǒng)可能的性能瓶頸在哪。
如下是一次摸底測試的配置和結(jié)果。這是用12000并發(fā)用戶對10臺機(jī)器壓測的結(jié)果,可以看出,TPS到7w多,平均響應(yīng)時間為82ms,錯誤率在2.5%。
從圖中還可以得到哪些信息?首先,TPS在后期迅速下落,實際上已經(jīng)支撐不了如此大的并發(fā)量,即進(jìn)入崩潰區(qū),這里有幾個可能,一是系統(tǒng)根本承受不了如此大的并發(fā)量,二是系統(tǒng)中間有問題導(dǎo)致TPS下跌。其次,隨著時間增長,錯誤率顯著增加,說明系統(tǒng)已經(jīng)處理不了如此多的請求。結(jié)合前面兩點以及相對平穩(wěn)的平均響應(yīng)時間,大致可以推斷系統(tǒng)沒法承受如此大的并發(fā)。另外,由于是10臺機(jī)器,單臺的TPS大概在7000多,今后的調(diào)優(yōu)可以以此為依據(jù)。
對于應(yīng)用的特點,也要在這時候分析出來,即應(yīng)用可能占用的資源。比如是CPU密集型應(yīng)用還是IO密集型應(yīng)用(還可以細(xì)分為是磁盤密集還是網(wǎng)絡(luò) )







2.定義性能優(yōu)化的目標(biāo)

經(jīng)常聽到人說,做個性能優(yōu)化,吞吐量越高越好;或者做個性能測試,目標(biāo)TPS是50000??蓪嶋H拿到這個信息,能夠做性能測試嗎?這個目標(biāo)足夠清晰嗎?
事實上,在我看來,未定義清晰的目標(biāo)去做性能測試都是耍流氓。
性能優(yōu)化的目標(biāo)一般是吞吐量達(dá)到多少,90%響應(yīng)時間小于多少,錯誤率小于多少。同時還需要關(guān)注其他的性能指標(biāo),cpu使用情況,內(nèi)存使用情況,磁盤使用情況,帶寬使用情況等。對于摸底測試已經(jīng)發(fā)現(xiàn)問題的,可以針對該問題專門優(yōu)化,比如負(fù)載較高,cpu消耗過大,則目標(biāo)可能是TPS,響應(yīng)時間以及錯誤率不變的情況下降低CPU負(fù)載?;蛘邇?nèi)存增長過快,gc較為頻繁,則目標(biāo)可能是找出可能的內(nèi)存泄露,或者進(jìn)行相關(guān)的jvm內(nèi)存調(diào)優(yōu)。總之,目標(biāo)可以比較靈活調(diào)整,但一定要明確。
3.分析
分析的過程較為靈活,基本上是一千個系統(tǒng)有一千種表現(xiàn)。這里很難一一說明。僅談?wù)勔恍┏R姷姆椒?,工具以及思路?br> 針對CPU
針對cpu的監(jiān)控,其實linux已經(jīng)提供了兩個比較好用的工具,一個是top,一個是vmstat。關(guān)于這兩個命令就不細(xì)說了,參考這里tophttp://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/top.html),vmstathttp://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/vmstat.html
關(guān)于cpu主要關(guān)注4個值:us(user), sy(system), wa(wait), id(idle)。理論上他們加起來應(yīng)該等于100%。而前三個每一個值過高都有可能表示存在某些問題。
us過高
a. 代碼問題。比如一個耗時的循環(huán)不加sleep,或者在一些cpu密集計算(如xml解析,加解密,加解壓,數(shù)據(jù)計算)時沒處理好
b. gc頻繁。一個比較容易遺漏的問題就是gc頻繁時us容易過高,因為垃圾回收屬于大量計算的過程。gc頻繁帶來的cpu過高常伴有內(nèi)存的大量波動,通過內(nèi)存來判斷并解決該問題更好。
小技巧:如何定位us過高的線程并查看它的狀態(tài)。
a. top命令找到消耗us過高的進(jìn)程pid
b. top -Hp pid找到對應(yīng)的線程tid
c. printf %x tid轉(zhuǎn)為16進(jìn)制tid16
d. jstack pid | grep -C 20 tid16 即可查到該線程堆棧
sy過高
a. 上下文切換次數(shù)過多。通常是系統(tǒng)內(nèi)線程數(shù)量較多,并且線程經(jīng)常在切換,由于系統(tǒng)搶占相對切換時間和次數(shù)比較合理,所以sy過高通常都是主動讓出cpu的情況,比如sleep或者lock wait, io wait。
wa過高
a. 等待io的cpu占比較多。注意與上面情況的區(qū)別,io wait引起的sy過高指的是io不停的wait然后喚醒,因為數(shù)量較大,導(dǎo)致上下文切換較多,強(qiáng)調(diào)的是動態(tài)的過程;而io wait引起的wa過高指的是io wait的線程占比較多,cpu切換到這個線程是io wait,到那個線程也是io wait,于是總cpu就是wait占比較高。
id過高
a. 很多人認(rèn)為id高是好的,其實在性能測試中id高說明資源未完全利用,或者壓測不到位,并不是好事。

針對內(nèi)存
關(guān)于java應(yīng)用的內(nèi)存,通常只需要關(guān)注jvm內(nèi)存,但有些特殊情況也需要關(guān)注物理內(nèi)存。關(guān)于jvm內(nèi)存,常見的工具有jstat(http://blog.csdn.net/fenglibing/article/details/6411951), jmap(http://www.cnblogs.com/ggjucheng/archive/2013/04/16/3024986.html), pidstat(https://linux.cn/article-4257-1.html), vmstat, top
jvm內(nèi)存
**異常gc **:
a. 通常gc發(fā)生意味著總歸是有一塊區(qū)域空間不足而觸發(fā)gc。而許多導(dǎo)致異常gc的情況通常是持有了不必要的引用而沒有即時的釋放,比如像cache這樣的地方就容易處理不好導(dǎo)致內(nèi)存泄露引發(fā)異常gc。
b. 有可能是程序的行為是正常的,但是由于沒有配置對合適的gc參數(shù)導(dǎo)致異常gc,這種情況通常需要調(diào)優(yōu)gc參數(shù)或者堆代大小參數(shù)。
c. Full gc 發(fā)生的情況:

永久代滿
年老代滿
minor gc晉升到舊生代的平均大小大于舊生代剩余大小
CMS gc中promotion fail或concurrent mode fail

OOM
a. OOM經(jīng)常伴隨著異常gc,之所以單獨拿出來講,是因為它的危害更大一些,異常gc頂多是收集速度過快或者回收不了內(nèi)存,但是起碼有個緩沖時間,但是出了OOM問題就大了。至于各種類型的OOM如何區(qū)分,如何發(fā)生,請參考這里(http://www.itdecent.cn/p/2fdee831ed03),算是總結(jié)得比較全面的。對于常見的OOM,基本上可以一下子指出問題所在。
b. heap區(qū),對象創(chuàng)建過多或持有太多無效引用(泄露)或者堆內(nèi)存分配不足。使用jmap找到內(nèi)存中對象的分布,使用ps找到相應(yīng)進(jìn)程及初始內(nèi)存配置。
c. stack區(qū), 不正確的遞歸調(diào)用。
d. perm區(qū),初始加載包過多,分配內(nèi)存不足。
e. 堆外內(nèi)存區(qū),分配ByteBuffer未釋放導(dǎo)致。

針對IO
IO分為網(wǎng)絡(luò)IO和文件IO,針對網(wǎng)絡(luò)IO比較有用的工具有sarhttps://linuxstory.org/generate-cpu-memory-io-report-sar-command/),netstathttps://linux.cn/article-2434-1.html),netstat是一個非常牛逼的命令,可以助于排查很多問題, 針對文件io的工具有pidstat,iostathttp://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/iostat.html
文件IO
a. 從技術(shù)上來說,對于大文件IO可以采取的措施是異步批處理,采用異步方式用于削峰并累計buffer,采用批處理能夠讓磁盤尋道連續(xù)從而更加快速。
網(wǎng)絡(luò)IO:網(wǎng)絡(luò)IO的問題較為復(fù)雜,僅舉幾個常見的
a. 大量TIME_WAIT。根據(jù)TCP協(xié)議,主動發(fā)起關(guān)閉連接的那一方,關(guān)閉了自己這端的連接后再收到被動發(fā)起關(guān)閉的那一方的關(guān)閉請求后,會將狀態(tài)變?yōu)門IME_WAIT,并等待2MSL, 目的是等待自己的回執(zhí)發(fā)送到對方。如果在服務(wù)器上發(fā)現(xiàn)大量TIME_WAIT,說明服務(wù)器主動斷開了連接,什么情況下服務(wù)器會主動斷開連接,很可能是客戶端忘了斷開連接,所以一個典型的案例就是jdbc連接忘記關(guān)閉,則數(shù)據(jù)庫服務(wù)器可能會出現(xiàn)大量的TIME_WAIT狀態(tài)。
b. 大量CLOSE_WAIT。CLOSE_WAIT狀態(tài),在收到主動關(guān)閉連接的一方發(fā)出關(guān)閉連接之后,被動關(guān)閉的一方進(jìn)入CLOSE_WAIT狀態(tài),如果這時候被hang住了沒進(jìn)行后續(xù)關(guān)閉,則會出現(xiàn)大量CLOSE_WAIT。啥情況會被hang住呢,舉幾個例子,比如剛剛的忘記關(guān)閉數(shù)據(jù)庫連接,在應(yīng)用服務(wù)器這端,大量的瀏覽器請求進(jìn)來,由于沒有連接池連接被hang住,這時候瀏覽器等待一定時間超時發(fā)送關(guān)閉連接請求,而應(yīng)用服務(wù)器這邊由于servlet線程被hang住了,自然沒有辦法走第二個關(guān)閉回去。因此在應(yīng)用服務(wù)器出現(xiàn)大量CLOSE_WAIT。另一個例子是httpClient的坑,在調(diào)用response.getEntity(); 前都不會做inputStream.close(),如果在調(diào)用response.getEntity()前就返回了,就狗帶了。(這個例子可以參考http://blog.csdn.net/shootyou/article/details/6615051

4.****優(yōu)化并重新測試驗證

性能調(diào)優(yōu)思路 http://www.voidcn.com/blog/bigtree_3721/article/p-5786972.html
linux下性能監(jiān)控命令 http://linuxtools-rst.readthedocs.io/zh_CN/latest/advance/index.html
關(guān)于JVM CPU資源占用過高的問題排查 http://my.oschina.net/shipley/blog/520062
java排查工具 http://my.oschina.net/feichexia/blog/196575
jvm參數(shù)調(diào)優(yōu) http://www.cnblogs.com/java-zhao/archive/2016/02/08/5185092.html
java linux系統(tǒng)調(diào)優(yōu)工具 https://www.ibm.com/developerworks/cn/java/j-lo-performance-tuning-practice/
gc優(yōu)化的一些思路 http://mm.fancymore.com/reading/gc%E4%BC%98%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E8%B7%AF.html
性能優(yōu)化的思路和步驟 http://www.uml.org.cn/j2ee/201602013.asp
性能調(diào)優(yōu)攻略 http://coolshell.cn/articles/7490.html
JVM性能調(diào)優(yōu)入門 http://www.itdecent.cn/p/c6a04c88900a
JVM性能調(diào)優(yōu) http://blog.csdn.net/chen77716/article/details/5695893
Tomcat性能優(yōu)化 https://yq.aliyun.com/articles/38861?utm_campaign=wenzhang&utm_medium=article&utm_source=QQ-qun&2017323&utm_content=m_14698

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java 應(yīng)用性能優(yōu)化是一個老生常談的話題,典型的性能問題如頁面響應(yīng)慢、接口超時,服務(wù)器負(fù)載高、并發(fā)數(shù)低,數(shù)據(jù)庫頻...
    Rick617閱讀 7,606評論 1 9
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,800評論 11 349
  • 某月黑風(fēng)高之夜,某打車平臺上線了一大波(G+)優(yōu)惠活動,眾人紛紛下單。于是乎,該打車平臺使用的智能提示服務(wù)扛不住直...
    古佛青燈度流年閱讀 3,200評論 0 8
  • 素手冰玉凝 弄水挽衫青 妝半淚晶瑩 銀生銅鏡 嘆年歲無情 相請復(fù)相請 郎君約不停 夸捧日月星 無窮光明 傻傻正妙齡...
    夾餡鍋鍋閱讀 374評論 2 2
  • 之前的兩期我們聊過了PPT動畫里面出鏡率相當(dāng)高的2個效果,“淡出”和“擦除”,需要回顧下他們用法的小伙伴,可以...
    愛睡覺de豬閱讀 1,340評論 2 15

友情鏈接更多精彩內(nèi)容