应用性能问题解决实际案例
某項(xiàng)目在上線前的APT(Application Performance Testing應(yīng)用程序性能測(cè)試)過(guò)程中發(fā)現(xiàn)性能問(wèn)題,性能測(cè)試結(jié)果影響是否上線,緊急求助外部項(xiàng)目組技術(shù)專家。
因分屬不同項(xiàng)目,只能通過(guò)項(xiàng)目組提供的信息進(jìn)行分析。
第一輪評(píng)審
現(xiàn)象
根據(jù)APT性能監(jiān)控截圖,左圖為并發(fā)用戶數(shù)和CPU使用率,右圖為單獨(dú)的CPU使用率情況。APT測(cè)試情景為并發(fā)用戶數(shù)以5分鐘為周期進(jìn)行增加,增加用戶數(shù)25人,在40分鐘后達(dá)到最終200并發(fā)用戶并保持1小時(shí)200用戶活動(dòng)狀態(tài)。
很明顯看出用戶穩(wěn)定后CPU使用率還在持續(xù)增長(zhǎng),懷疑有內(nèi)存泄露問(wèn)題。
?
?
分析
第一輪我們拿到的是API源代碼,日志里面出現(xiàn)outOfMemory錯(cuò)誤,檢查一遍發(fā)現(xiàn)API控制器方法中創(chuàng)建了HttpClient實(shí)例。詢問(wèn)開(kāi)發(fā)組回復(fù)是因?yàn)槊看握?qǐng)求URL不同,根據(jù)經(jīng)驗(yàn)推薦采用HttpWebRequest替換調(diào)HttpClient。同時(shí)我們調(diào)查是否是由HttpClient引起的內(nèi)存泄漏問(wèn)題。
由Google搜索結(jié)果HttpClient確實(shí)有內(nèi)存泄漏的報(bào)告,我們著手寫了一個(gè)小程序比較HttpClient和HttpWebRequest性能,并通過(guò)JMeter在本地進(jìn)行性能測(cè)試。
HttpClient和HttpWebRequest性能比較
測(cè)試環(huán)境
測(cè)試URL:?https://www.baidu.com/#{number}?(number變量為隨機(jī)或遞增以防止HTTP緩存干擾性能對(duì)比結(jié)果)
測(cè)試節(jié)奏:10秒周期,并發(fā)用戶從1到200增長(zhǎng)
測(cè)試結(jié)果(內(nèi)存使用量)
HttpClient: 455MB
HttpWebRequest: 242MB
圖1: HttpClient (GetAsync)
?
圖2: HttpWebRequest (請(qǐng)忽略結(jié)尾處由網(wǎng)絡(luò)連接問(wèn)題出現(xiàn)的凸起)
?
結(jié)論
將HttpClient更換使用HttpWebRequest,但根據(jù)HttpClient內(nèi)存使用陡增幅度估計(jì)還有其它問(wèn)題,通知開(kāi)發(fā)組繼續(xù)調(diào)查并提供相關(guān)資料。
第二輪評(píng)審
現(xiàn)象
比較IIS內(nèi)存使用和SQL Server的內(nèi)存使用發(fā)現(xiàn)相同的增長(zhǎng)趨勢(shì),猜測(cè)瓶頸出現(xiàn)在數(shù)據(jù)庫(kù)查詢中(如果是拒絕訪問(wèn)數(shù)據(jù)庫(kù)不會(huì)出現(xiàn)內(nèi)存增長(zhǎng),一定是已經(jīng)連接了數(shù)據(jù)庫(kù)并產(chǎn)生查詢問(wèn)題導(dǎo)致)。
推薦增加查詢操作日志獲得查詢執(zhí)行時(shí)間,安裝數(shù)據(jù)庫(kù)性能監(jiān)視工具(可使用Windows Server自帶的Performance Monitor或者第三方工具如AppDynamic),查看查詢的執(zhí)行計(jì)劃(Execution Plan)。
圖3: SQL Server – 內(nèi)存 - % committed Bytes (內(nèi)存使用)
?
圖4: MS IIS – 內(nèi)存 - % Committed Bytes (內(nèi)存使用)
?
同時(shí)經(jīng)過(guò)了解API還會(huì)調(diào)用上游系統(tǒng)的API(API嵌套),所以考慮檢查日志是否存在因上游API瓶頸導(dǎo)致調(diào)用失敗,導(dǎo)致異常阻塞請(qǐng)求進(jìn)程。也會(huì)出現(xiàn)相同的現(xiàn)象,開(kāi)發(fā)組著手調(diào)查。
上游API問(wèn)題通過(guò)調(diào)整系統(tǒng)配置消除瓶頸,但SQL Server性能問(wèn)題還無(wú)任何頭緒。只能安排時(shí)間一起評(píng)審數(shù)據(jù)庫(kù)及相應(yīng)查詢性能問(wèn)題。
第三輪評(píng)審
背景:
測(cè)試總時(shí)長(zhǎng)1小時(shí)40分:從最開(kāi)始每隔1分鐘增長(zhǎng)5個(gè)并發(fā)用戶,40分鐘左右并發(fā)數(shù)加到200,然后維持并發(fā)用戶不變,又執(zhí)行1小時(shí)
現(xiàn)象:
達(dá)到200并發(fā)后的20分左右時(shí), CPU的使用率達(dá)到30% 左右之后保持相對(duì)平穩(wěn)的比例,但是在這之后的執(zhí)行過(guò)程中 request queued 曲線出現(xiàn)排隊(duì)現(xiàn)象, Thread Count 曲線出現(xiàn)突然增長(zhǎng)的情況,并且同是response time 翻倍增長(zhǎng)。
上次報(bào)告沒(méi)有HTTP 5xx錯(cuò)誤,本次出現(xiàn)HTTP 5xx錯(cuò)誤,27日錯(cuò)誤數(shù)量激增。
程序中有從上百萬(wàn)條數(shù)據(jù)中抽取數(shù)據(jù)生成級(jí)聯(lián)選擇(下拉菜單)的UI元素。
程序中使用了Http Cache,但在準(zhǔn)備Cache數(shù)據(jù)的邏輯中沒(méi)有鎖處理,數(shù)據(jù)準(zhǔn)備時(shí)間過(guò)長(zhǎng),就會(huì)造成期間大量請(qǐng)求訪問(wèn)數(shù)據(jù)庫(kù)。
性能測(cè)試報(bào)告中SQL Server也顯示出周期性達(dá)到100% CPU利用率,引發(fā)數(shù)據(jù)庫(kù)連接超時(shí),同時(shí)應(yīng)用程序出現(xiàn)GATEWAY_TIMEOUT。
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: Timeout expired.? The timeout period elapsed prior to obtaining a connection from the pool.? This may have occurred because all pooled connections were in use and max pool size was reached.
?
?
?
分析
因已經(jīng)做過(guò)兩輪評(píng)審,開(kāi)發(fā)組這次提供了全面的資料,通過(guò)代碼評(píng)審發(fā)現(xiàn)邏輯中有使用LDAP(Windows活動(dòng)目錄輕量目錄訪問(wèn)協(xié)議Light Directory Access Protocol)遍歷登陸者所有活動(dòng)目錄下的組。
此邏輯可能會(huì)產(chǎn)生請(qǐng)求ADFS查詢的瓶頸,阻塞請(qǐng)求。
同時(shí)發(fā)現(xiàn)部分被查詢的表中沒(méi)有創(chuàng)建索引(這個(gè)是在最初問(wèn)過(guò)開(kāi)發(fā)團(tuán)隊(duì)但得到的回答是肯定的)并進(jìn)行索引優(yōu)化,另外,API采用.NET Entity Framework編寫,由SQL查詢監(jiān)控看出因無(wú)索引導(dǎo)致EF生成相同表的嵌套(笛卡爾積)查詢,是導(dǎo)致表遍歷和產(chǎn)生表鎖的主要原因。
對(duì)于大量出現(xiàn)的5xx錯(cuò)誤,因上次性能測(cè)試沒(méi)有,主要針對(duì)修改的代碼進(jìn)行評(píng)審發(fā)現(xiàn)增加了EF查詢邏輯,這也是導(dǎo)致循環(huán)嵌套的原因。
結(jié)論
表索引優(yōu)化是主要解決辦法。EF查詢最終改為明文查詢并SQL查詢優(yōu)化。
總結(jié)
性能問(wèn)題首先由測(cè)試入手,根據(jù)測(cè)試報(bào)告發(fā)現(xiàn)錯(cuò)誤和性能瓶頸,主要以解決錯(cuò)誤消除瓶頸為主要原則。對(duì)于有數(shù)據(jù)庫(kù)存在的情景,注意查詢和索引優(yōu)化,保證連接池有效支持應(yīng)用并發(fā)。問(wèn)題調(diào)研期間要了解整體架構(gòu)(本次API嵌套問(wèn)題和LDAP的使用都是后期由開(kāi)發(fā)組告知)和所使用的技術(shù),才能給出全面建議。從開(kāi)發(fā)組角度應(yīng)該訓(xùn)練發(fā)現(xiàn)性能問(wèn)題的敏感度。所有問(wèn)題的發(fā)現(xiàn)和解決以測(cè)試事實(shí)數(shù)據(jù)說(shuō)話,不會(huì)存在莫須有的性能問(wèn)題,所有問(wèn)題皆有因緣。
原文地址:https://www.cnblogs.com/richardcuick/p/11008387.html
總結(jié)
以上是生活随笔為你收集整理的应用性能问题解决实际案例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: NopCommerce 4.2的安装与运
- 下一篇: 记录一次生产发布事件——(简单的非空验证