性能測試相關

性能測試相關概念

并發(fā)用戶數(shù)(VU):?系統(tǒng)同時處理的request/事務數(shù)

QPS(TPS)(transaction per second):每秒鐘處理request/事務?數(shù)量

響應時間rt:??一般取平均響應時間

這三個參數(shù)是一組,理論上,并發(fā)數(shù)=QPS*rt,當QPS*rt<并發(fā)數(shù) 時,這時的壓力就接近系統(tǒng)所能承受的最大壓力了,也就是接近了系統(tǒng)瓶頸。

cpu使用率:cpu被占用的情況,一般要保證在75%以下

load:系統(tǒng)平均負載,被定義為在特定時間間隔(1m,5m,15m)內(nèi)運行隊列中的平均進程數(shù)。

前后優(yōu)化耗時:

1. 慎用try-catch,尤其是在循環(huán)之中,可以的話將其移到循環(huán)之外。循環(huán)內(nèi)110ms,循環(huán)外62ms

2. 多用局部變量。由于局部變量在棧中,其它如靜態(tài)變量的多在堆中,相比之下變量在棧中會更優(yōu)秀一些。使用static變量266ms,使用局部變量78ms。

3.位運算代替乘、除法。原219ms,位運算后31ms。

4.switch在循環(huán)中可以用數(shù)組代替(書中理論)。比較有意思的是我的本機上跑循環(huán)中switch耗時8ms,用map/array替代耗時32ms。

5.提取公共表達式。提取前156ms,提取后78ms。

6.展開循環(huán),拉開迭代器增長步長。有必要說一下,這會導致可讀性變差,也是沒有辦法的辦法才這么搞。優(yōu)化前94ms,優(yōu)化后31ms。

7.靜態(tài)static方法代替實例方法。

并發(fā)過程的優(yōu)化,這里也是有優(yōu)化策略的。首先由于數(shù)據(jù)同步,并發(fā)結構需要更改如下:

List : Collections.synchronizedList(List)

Set : Collections.synchronizedList(Set)

HashMap : concurrentHashMap

Queue : concurrentLinkedQueue

volatile : 變量其它線程可見

synchronized : 鎖方法,內(nèi)部鎖

ReadWriteLock : 重入鎖

ThreadLocal : 局部變量,每個變量一個副本

semaphore :信號量,指定多個線程同時訪問某一資源

關于鎖,有以下幾種方法:

1. 減小鎖的范圍,舉個例子,如果某條記錄操作數(shù)據(jù)庫,如果可以將這條記錄鎖住,那就千萬不要用鎖整個數(shù)據(jù)庫的方式,而使用將這條記錄鎖住。

2.減小鎖粒度。如concurrentHaspMap結構,其內(nèi)部是分為16段的,減少Hash時沖突問題。當然這也存在一個問題,就是concurrentHaspMap作為全局使用時,需要獲取全部的16個鎖。

3.鎖分離。LinkedBlockingQueue,基于鏈表前端、尾端同時操作;此外讀寫分離鎖(針對讀多寫少的情況)也是這個思想。

4.鎖粗化:循環(huán)內(nèi)頻繁使用鎖時,放在循環(huán)之外。

nGrinder

http://blog.csdn.net/neven7/article/details/50740018


Android 性能測試總結

啟動時間

啟動時間一般我們會測試三種情況。

首次啟動

非首次啟動

activity 切換所消耗的時間

測試方法一般使用兩種:

1、程序內(nèi)部打點到logcat,手動操作后獲取log日志,來獲取相應的時間。

2、使用adb 命令來操作,在操作的前后分別記錄消耗的時間。(由于adb 操作可能會有延時等可能,此方法并不是很準確)

ps. 還有一種方式是采用告訴攝像機的方式來做,由于本人沒有接觸過,不過多說明。

cpu和內(nèi)存

1、獲取cpu數(shù)據(jù)

adb shell dumpsys cpuinfo |grep$package_name

輸出格式為;

45% TOTAL:18%user+ 20% kernel +6.2% iowait +0.2% softirq

可取total得值作為整體cpu利用率。

2、獲取內(nèi)存數(shù)據(jù)

adb shell dumpsys meminfo |grep$package_name

或者

adbshell dumpsys meminfo$package_name

直接dumpsys meminfo $package_name 可以看到比較完整的堆,線程,java等級別的內(nèi)存數(shù)據(jù),pss 可以作為內(nèi)存的參考。

2、使用top 同時獲取cpu和內(nèi)存,-d 參數(shù)指定采樣數(shù)據(jù)的間隔時間。

adb shell top-d2

輸出:

PIDPR CPU% S#THR? ? VSS? ? RSS PCY UID? ? ? Name

名詞解釋:

VSS- Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫占用的內(nèi)存)

RSS- Resident Set Size 實際使用物理內(nèi)存(包含共享庫占用的內(nèi)存)

PSS- Proportional Set Size 實際使用的物理內(nèi)存(比例分配共享庫占用的內(nèi)存)

USS- Unique Set Size 進程獨自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存)

一般來說內(nèi)存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS

可以看到,top 命令取出的內(nèi)存對應是vss 和 rss,其中rss會比pss稍大,如果沒有特別嚴格的要求,只是對比內(nèi)存是否泄漏上漲等問題,rss也可以作為參考。

流量

1、通過tcpdump抓包,然后wireshark 解包信息,來獲取流量數(shù)據(jù)。

2、通過adb 命令來獲取,先獲取應用的pid,然后通過/proc/uid_stat/uid/下的文件來讀取流量值。此方式會有rom兼容性問題,并不是所有的文件都可以找到這兩個文件。

adbshelldumpsys$package_nameadbshellcat/proc/uid_stat/uid/tcp_rcv? -- 下載流量adbshellcat/proc/uid_stat/uid/tcp_snd? -- 上傳流量

由于tcp_rcv, tcp_snd 的值是一個累加的值,想要獲取兩次操作間消耗的流量,可以在操作前和操作后分別獲取,差值即為期間消耗的流量。也可以每個一段時間做采樣,來獲取整個過程中的使用情況。

幀率

幀率一定程度上反應的是app在使用中的流暢程度,理想情況是每秒60幀。

1、在開發(fā)者選項中有個“ GPU呈現(xiàn)模式分析(Profile GPU rendering,計算adb shell dumpsys gfxinfo中的呈現(xiàn)時間)”功能,在開啟這個功能后,系統(tǒng)就會記錄保留每個界面最后128幀圖像繪制的相關時間信息。在開啟這個功能后,重新啟動APP,滑動頁面然后執(zhí)行adb命令。

adbshell dumpsys gfxinfo$package_name

輸出結果中包含這部分數(shù)據(jù)

DrawProcessExecute1.301.250.530.630.621.640.240.510.440.251.760.400.251.550.430.250.530.370.491.512.12

Draw: 表示在Java中創(chuàng)建顯示列表部分中,OnDraw()方法占用的時間。

Process:表示渲染引擎執(zhí)行顯示列表所花的時間,view越多,時間就越長。

Execute:表示把一幀數(shù)據(jù)發(fā)送到屏幕上排版顯示實際花費的時間。其實是實際顯示幀數(shù)據(jù)的后臺緩存區(qū)與前臺緩沖區(qū)交換后并將前臺緩沖區(qū)的內(nèi)容顯示到屏幕上的時間。

Draw + Process + Execute = 完整顯示一幀 ,這個時間要小于16ms才能保存每秒60幀。

2、通過SurfaceFlinger, 這種方式還沒有研究過,過段時間再來補充

adb shell dumpsys SurfaceFlinger

電量

1、對于電量的測試沒有什么特別好的方式,可以選擇使用物理設備來測試電池的電量情況。

2、對于android 5.0 以上的系統(tǒng),adb命令可以支持獲取電量信息。

adbshelldumpsysbattery

輸出內(nèi)容如下:

ACpowered:falseUSBpowered:trueWirelesspowered:falsestatus:1#電池狀態(tài):2:充電狀態(tài) ,其他數(shù)字為非充電狀態(tài)health:2present:truelevel:55#電量: 百分比scale:100voltage:3977currentnow:-335232temperature:335#電池狀態(tài)technology:Li-poly

jvm的調(diào)優(yōu)

查看堆空間大小分配(年輕代、年老代、持久代分配)

垃圾回收監(jiān)控(長時間監(jiān)控回收情況)

?線程信息監(jiān)控:系統(tǒng)線程數(shù)量

線程狀態(tài)監(jiān)控:各個線程都處在什么樣的狀態(tài)下

線程詳細信息:查看線程內(nèi)部運行情況,死鎖檢查

CPU熱點:檢查系統(tǒng)哪些方法占用了大量CPU時間

內(nèi)存熱點:檢查哪些對象在系統(tǒng)中數(shù)量最大

服務器性能瓶頸如何定位

https://www.cnblogs.com/mumulog/p/11455018.html

CPU定位分析

CPU利用率大于50%,需要注意;大于75%,需要密切關注;高于90%-95%,情況比較嚴重;

監(jiān)控命令:vmstat、sar、dstat、mpstat、top、ps

類型度量方法衡量標準

利用率

1、vmstat統(tǒng)計1-%idle

2、sar -u統(tǒng)計1-%idle

3、dstat統(tǒng)計1-%idl

4、mpstat -P ALL統(tǒng)計1-%idle

注意>=50%

告警>=70%

嚴重>=90%

滿載

1、vmstat的r值>? cpu邏輯顆數(shù)

2、sar -q ,“runq-sz”>cpu邏輯顆數(shù)

運行隊列大于1時,證明已經(jīng)有一定的負載

內(nèi)存定位分析

當物理內(nèi)存不夠時,會使用swap分區(qū),所以性能測試過程中需要關注swap和mem的使用情況。

物理內(nèi)存不夠,大量的內(nèi)存置換到swap空間,可能導致CPU和I/O的瓶頸。

監(jiān)控命令:vmstat、sar、dstat、free、top、ps等

類型度量方法衡量標注

占用率

1、free 查看使用情況

2、vmstat

3、sar -r

4、ps

注意>=50%

告警>=70%

嚴重>=80%

滿載

1、vmstat的si/so比例,swapd占比

2、sar -W 查看次缺頁數(shù)

3、dmesg | grep killed

1、so數(shù)值大,且swapd已經(jīng)占比很高,內(nèi)存已經(jīng)飽和

2、sar命令次缺頁多意味內(nèi)存已經(jīng)飽和

3、內(nèi)存不夠用會觸發(fā)內(nèi)核的OOM機制

網(wǎng)絡定位分析

監(jiān)控命令:sar、ifconfig、netstat,以及查看net的dev速率。

通過查看發(fā)現(xiàn)收發(fā)包的吞吐率達到網(wǎng)卡的最大上限,網(wǎng)絡數(shù)據(jù)報文有因為這類原因而引起的丟包、阻塞等現(xiàn)象都證明當前網(wǎng)絡可能存在瓶頸。

為了減小網(wǎng)絡對性能測試的影響,一般我們都在局域網(wǎng)中進行測試執(zhí)行。

類型度量方法衡量標準

使用情況

1、sar -n DEV 的收發(fā)計數(shù)大于網(wǎng)卡上限

2、ifconfig RX/TX寬帶超過網(wǎng)卡上限

3、cat /proc/net/dev的速率超過上限

4、nicstat的util基本滿負荷

1、收發(fā)包的吞吐率達到網(wǎng)卡上限

2、有延遲

3、有丟包

4、有阻塞

滿載1、ifconfig dropped 有計數(shù)

2、netstat -s "segments retransmited"有計數(shù)

3、sar -n EDEV,rxdrop/s ?txdrop/s有計數(shù)

有丟包統(tǒng)計

錯誤

1、ifconfig,“errors”

2、netstat -i,RX-ERR TX-ERR

3、sar -n EDEV,rxerr/s ? txerr/s?

4、ip -s link, “errors”

錯誤有計數(shù)? ?

IO定位分析

I/O讀寫頻繁的時候,如果I/O得不到滿足會導致應用的阻塞。

需要考慮I/O的TPS、平均I/O數(shù)據(jù)、平均隊列長度、平均服務時間、平均等待時間、IO利用率(磁盤Busy Time%)等指標

監(jiān)控命令:sar、iostat、iotop

類型度量方法衡量標準

使用情況

1、iostat -xz,“%util”

2、sar -d,“%util”

3、cat /proc/pid/sched | grep iowait

注意>=40%

告警>=60%

嚴重>=80%

滿載

1、iostat -xnz,“avgqu-sz?”>1

2、iostat await>70

IO疑似滿載

錯誤

1、dmseg 查看io錯誤

2、smartctl /dev/sda

有錯誤信息

Jmeter知識

一臺臺式機能支持的最大并發(fā)量 This is based on my experience If we follow the best practices as follow then we can achieve?350?~?500?concurrent users (web based application) and?900~1100?concurrent users (backend API) provided 8 GB RAM with 64-bit OS.

1、如何配置多個用戶--放在csv文件里面,進行調(diào)用

2、前面一個接口的返回值,比如登錄的token值,如何作為下一個接口的參數(shù),進行傳輸--后置處理器中的正則表達式去提取,或者json提取器

3、加密參數(shù)如何傳輸--調(diào)用一個函數(shù)--https://www.cnblogs.com/kikihuang/p/11475669.html

4、如何處理異步通信

https://blog.csdn.net/weixin_42484338/article/details/102851774?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.baidujs&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.baidujs

5、壓力測試在測試環(huán)境還是線上環(huán)境做?如果是測試環(huán)境做,如何保證和線上環(huán)境一樣?因為測試環(huán)境配置的服務器啥的大多和線上不一樣

6、分布式壓測了解一下

https://www.cnblogs.com/gcgc/p/11727761.html

https://www.cnblogs.com/dcszhangsir/p/13463299.html

7、根據(jù)測試報告的數(shù)據(jù),如何分析測試結果,并給出開發(fā)一些修改意見

8、壓力測試主要分析哪些測試指標

9、遇到過得測試出來的什么問題,是什么原因,給出了什么建議,大概講一下

gatling

全鏈路壓測

1)首先要梳理核心鏈路的流程,明確鏈路的邊界,核心鏈路是一個業(yè)務的核心,這一塊應該可以很快梳理清楚,但是,難點在于梳理清楚鏈路的邊界,分支業(yè)務

每個業(yè)務owner反復確認,哪些是核心業(yè)務,哪些是分支業(yè)務,哪些參與壓測,哪些不參與壓測,把這些形成文檔,逐個跟進。

2)提供全鏈路壓測的底層支持

我的理解:

流量、數(shù)據(jù)隔離 ,可以在head中打標

新建影子表,寫入和讀取都走影子表

日志-影子目錄:將壓測流量產(chǎn)生的日志落入到影子目錄

全鏈路透傳壓測標志:必須有一種在全鏈路透傳壓測標志的能力,并且必須基于一次請求,也就是同一個traceId,現(xiàn)在,大部分分布式業(yè)務都會接入trace系統(tǒng),例如,google的dapper,阿里的鷹眼等,對trace系統(tǒng)進行改造,使其能夠透傳壓測標志,需要透傳的路徑大概有:

? ? HTTP,RPC(DUBBO),MQ,線程池等

影子表:參與壓測的業(yè)務,要逐個排查自己依賴的數(shù)據(jù)庫,然后創(chuàng)建影子表,影子表必須跟正常表的schema保持一致,可以在每次壓測時候手動創(chuàng)建,也可以推動DBA自動創(chuàng)建。創(chuàng)建好影子表后,如果當前流量是壓測流量,那么寫入和讀取都走影子表。如果有自己的數(shù)據(jù)庫中間件最好,沒有的話可以借助于Mybatis的Interceptor機制。

日志-影子目錄:為了防止壓測流程的日志對正常日志造成干擾,需要改造日志組件,將壓測流量產(chǎn)生的日志落入到影子目錄。影子目錄可以有日志組件自動創(chuàng)建。

MQ支持是否消費壓測流量:有的時候,全鏈路會通過MQ進行傳遞,所以,必須在消費MQ的時候進行選擇:是否選擇消費壓測流量的MQ消息。這就需要對MQ系統(tǒng)進行改造,一方面使其可以透傳壓測流量,另一方面,需要支持配置是否消費壓測的MQ消息

緩存,大數(shù)據(jù)隔離:還有一些場景,比如,緩存層,大數(shù)據(jù)層對壓測流量的處理也要考慮隔離。緩存可以使用不同的集群;大數(shù)據(jù)可以直接不收集壓測的數(shù)據(jù)

3)思考全鏈路壓測的數(shù)據(jù)怎么mock

在使用影子表之后,可以比較輕松的實現(xiàn)跟正常數(shù)據(jù)隔離,那剩下的就是好構造好mock數(shù)據(jù),有幾點需要考慮:

① 用戶數(shù)據(jù)要提前做好認證等準備工作

②? Mock數(shù)據(jù)要盡可能跟真實數(shù)據(jù)保持一致,比如,價格水平,圖片數(shù)量,地址信息等等

③? Mock數(shù)據(jù)有些限制需要放開,比如,庫存,一些運營性質(zhì)的活動可以取消等

④ 千萬不要污染正常數(shù)據(jù):認真梳理數(shù)據(jù)處理的每一個環(huán)節(jié),確保mock數(shù)據(jù)的處理結果不會寫入到正常庫里面

4)梳理監(jiān)控體系

① 核心接口和核心依賴的流量和耗時監(jiān)控

② 中間件組件,緩存,數(shù)據(jù)庫的監(jiān)控報警

③ 機器的指標報警

5)線下做好預演

真實的壓測之前,肯定要進行預演,預演主要確認:

① 壓測流程是否寫入到了正確的目的地,例如,寫入到影子表,影子目錄,壓測cache等等

② 壓測流量的降級是否完備和有效

③ 進一步確保監(jiān)控都已到位

6)盡量模擬現(xiàn)實,用戶的行為,例如

① 購買的行為:不是下單后立即購買,而是要等一下子

② 騎車子的行為:開鎖后并不是里面換車,而是騎一會

7)逐步平滑加壓

壓測的時候,逐步加壓,并且要保持平滑加壓,不要把一秒的流量都在前面幾毫秒內(nèi)都壓出去。

難點: 推進

全鏈路壓測的技術難點不多,除了要花時間梳理流程和思考如何處理數(shù)據(jù)之外,最難的就是整個鏈路跨多個業(yè)務,甚至部門,需要跟進每個業(yè)務線的進度,確保大家能夠在給定的時間點進行聯(lián)調(diào)以及進行壓測。在推進的時候,按照核心鏈路所在的模塊進行跟進,每個模塊出一個owner,各個owner跟進核心的接口和依賴,每周大家碰一下同步下總體的進度

壓測中TPS上不去,那么你怎么分析這個問題?

1、網(wǎng)絡帶寬

在壓力測試中,有時候要模擬大量的用戶請求,如果單位時間內(nèi)傳遞的數(shù)據(jù)包過大,超過了帶寬的傳輸能力,那么就會造成網(wǎng)絡資源競爭,間接導致服務端接收到的請求數(shù)達不到服務端的處理能力上限。

2、連接池

可用的連接數(shù)太少,造成請求等待。連接池一般分為服務器連接池(比如Tomcat)和數(shù)據(jù)庫連接池(或者理解為最大允許連接數(shù)也行)。

3、垃圾回收機制

從常見的應用服務器來說,比如Tomcat,因為java的的堆棧內(nèi)存是動態(tài)分配,具體的回收機制是基于算法,如果新生代的Eden和Survivor區(qū)頻繁的進行Minor GC,老年代的full GC也回收較頻繁,那么對TPS也是有一定影響的,因為垃圾回收其本身就會占用一定的資源。

4、數(shù)據(jù)庫配置

高并發(fā)情況下,如果請求數(shù)據(jù)需要寫入數(shù)據(jù)庫,且需要寫入多個表的時候,如果數(shù)據(jù)庫的最大連接數(shù)不夠,或者寫入數(shù)據(jù)的SQL沒有索引沒有綁定變量,抑或沒有主從分離、讀寫分離等,就會導致數(shù)據(jù)庫事務處理過慢,影響到TPS。

5、通信連接機制

串行、并行、長連接、管道連接等,不同的連接情況,也間接的會對TPS造成影響。

6、硬件資源

包括CPU(配置、使用率等)、內(nèi)存(占用率等)、磁盤(I/O、頁交換等)。

7、壓力機

比如jmeter,單機負載能力有限,如果需要模擬的用戶請求數(shù)超過其負載極限,也會間接影響TPS(這個時候就需要進行分布式壓測來解決其單機負載的問題)。

8、壓測腳本

還是以jemter舉個例子,之前工作中同事遇到的,進行階梯式加壓測試,最大的模擬請求數(shù)超過了設置的線程數(shù),導致線程不足。提到這個原因,想表達意思是:有時候測試腳本參數(shù)配置等原因,也會影響測試結果。

9、業(yè)務邏輯

業(yè)務解耦度較低,較為復雜,整個事務處理線被拉長導致的問題。

10、系統(tǒng)架構

比如是否有緩存服務,緩存服務器配置,緩存命中率、緩存穿透以及緩存過期等,都會影響到測試結果。

性能測試CPU占有率高如何定位問題?

通過Top命令查看具體的進程,然后使用相關的命令具體到線程,最后通過相關的工具查看棧的問題,以至于最后定位到代碼。

?總結:?

1. 查找進程

top查看進程占用資源情況

明顯看出java的那個進程占用過高cpu.

2.查找線程

使用top -H -p <pid>查看線程占用情況

3.查找java的堆棧信息

將線程id轉(zhuǎn)換成十六進制

#printf %x 15664

#3d30

然后再使用jstack查詢線程的堆棧信息

語法:jstack | grep -a?線程id(十六進制)

jstack <pid> | grep -a?3d30?

這樣就找出了有問題的代碼了。

?pid :進程id? ? ? ? ? ? ? ? tid :線程 id

https://blog.csdn.net/lord_is_layuping/article/details/90238816

MySQL查看SQL語句執(zhí)行效率

Explain命令在解決數(shù)據(jù)庫性能上是第一推薦使用命令,大部分的性能問題可以通過此命令來簡單的解決,Explain可以用來查看?SQL?語句的執(zhí)行效 果,可以幫助選擇更好的索引和優(yōu)化查詢語句,寫出更好的優(yōu)化語句。

Explain語法:explain select … from … [where ...]

https://blog.csdn.net/jwq101666/article/details/78561022

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

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

  • 壓力測試工具 jmeter Gatling 測試指標 吞吐(qps) .avg響應時間及.99(.999)響應時間...
    AGIHunt閱讀 1,036評論 0 10
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評論 25 709
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,787評論 11 349
  • 頁面適配 body的width為640 / 100 = 6.4remhtml font-size可能需要額外的媒...
    xiaomeimei閱讀 258評論 2 0
  • 早上的大雨傾盆,正在抹臉,被一陣電話引到客廳,原來女兒上學把鞋子弄濕了,叫我另送一雙鞋到學校保安室,隨后還說了聲謝...
    西畔閱讀 360評論 0 0

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