【轉】支付寶的性能測試

1、性能測試支付寶場景介紹

2013年雙11過程中,促銷開啓的第一分鐘內支付寶的交易總額就突破了一億元,短期內大量用戶涌入的狀況下,如何保證用戶的支付順暢,是對支付寶應用系統的一個極大的挑戰。java

支付寶的性能測試場景分爲性能基線測試,項目性能測試。linux

任意一筆交易過來,咱們都須要對交易進行風險掃描,對於有多是帳戶盜用的交易,咱們會把這筆支付直接拒絕掉,或者經過手機校驗碼等方式進行風險釋放。web

 

咱們有一個老的掃描平臺A,如今須要構建一個新的掃描平臺B,對A中關鍵技術進行升級,並增長額外的功能。掃描的策略是存儲在DB中的,須要經過發佈來更新到應用服務器的內存中。服務器

2、性能測試需求分析和方案制定

a. 需求挖掘網絡

1),查看業務方的顯性需求。業務方給到的需求爲平臺B的分析性能要優於平臺A的性能。除此以外無其它的需求。數據結構

 

2),挖掘隱性需求.瞭解業務架構,瞭解業務流程。爲了保證掃描的性能,大量的存儲類的需求被設計爲異步處理,可是結果類的掃描須要使用到前面落地的數據,那麼在系統正常運行時是否會存在落地數據讀取不到的問題,在存儲抖動時是否會致使後續的分析掃描所有失效?架構

首先咱們經過運維監控平臺拿到平臺A的分析性能,RT<130ms, TPS>35.

基於以上的需求挖掘,咱們確認的性能測試場景爲

  1. 掃描性能場景。(單場景)
  2. 發佈性能場景。(單場景)
  3. 掃描過程當中發佈性能場景。(混合場景)

b. 技術方案

1).評估咱們的系統架構,系統調到鏈路,定位可能存在問題的瓶頸點。

2).掌握詳細技術實現方案,瞭解具體技術方案可能存在的性能問題。

好比咱們是否使用到了腳本動態編譯,是Java腳本仍是groovy腳本。是否使用到了線程池等異步處理,系統冪等性是如何控制的,數據結構是如何存儲與讀取的,是決策樹仍是圖型結構。

3).瞭解系統環境的差別,好比服務器位數、CPU、內存的差別,JDK版本及位數的差別。

基於以上的技術方案,咱們確認了上述3個性能測試場景可能存在的性能問題

1. 掃描性能場景

技術方案爲掃描引擎drools2升級到了drools5.

性能關注點爲請求掃描RT,TPS是否知足咱們的需求;JVM Old區內存溢出,Old區內存泄露;GC 頻率太高。CPU使用率,load.

2. 發佈性能場景

技術方案爲規則DB撈取->規則加載->規則引擎切換->規則腳本編譯。

性能關注點爲CPU使用率,load。JVM Perm區內存溢出,Perm區內存泄露,GC 頻率太高。GC 暫停應用時間。

3. 掃描過程當中發佈性能場景。

性能關注點爲請求掃描RT,TPS。規則發佈耗時,CPU使用率,load, JVM GC頻率。

c. 性能測試方案制訂

  1. 分佈式壓測,參數自動化,使用單元測試腳本,接口測試腳本,jmeter腳本等進行壓測。
  2. 性能結果收集及統計。
  3. 性能測試經過標準。

基於以上的分析

1. 掃描性能場景

性能測試方案:

使用jmeter 腳本進行分佈式壓測,一臺master, 三臺slaver. 參數自動構建,使用高斯定時器模擬真實場景。

使用jmeter 收集分析性能數據,使用nmon收集服務器性能數據,使用jconsole收集JVM數據。

經過標準:

RT<130ms, TPS>35.

JVM old 區內無內存泄露,無內存溢出。GC時間間隔>30min,暫停應用時間<150ms.

CPU<70%, load < core*1.5。

2. 發佈性能場景

性能測試方案:

發佈時間間隔時間限制從1min調整爲3s, 更快的暴露問題。

使用單元測試類推送發佈消息。

服務器shell 腳本收集發佈模塊性能數據。

使用nmon收集服務器性能數據。

使用jconsole收集JVM數據。

經過標準:

JVM Perm 區內無內存泄露,無內存溢出。GC時間間隔>10min,暫停應用時間<200ms.

發佈時間<30S

CPU<70%, load < core*1.5。

3.掃描過程當中發佈性能場景

性能測試方案:

使用jmeter腳本進行分佈式壓測,同時提交發布請求進行發佈。

同時使用掃描性能場景和發佈性能場景收集數據功能。

經過標準:

RT < 掃描性能場景結果RT * 110%.

TPS >  掃描性能場景結果TPS * 90%.

發佈時間 < 40s。

d. 發現的問題

1. 掃描性能場景

AVG RT = 473ms, CMS GC = 90ms, 應用暫停時間 = 1s, 所以測試未經過。

問題定位:

dump內存,使用ibm memory analyzer 分析。

確認cms gc的緣由爲drools引擎的finalize方法。Finzlize方法不能正確的釋放對象的引用關係,致使引用關係一直存在,沒法釋放。

調優方案:

根據drools的升級文檔,升級drools引擎後解決此問題

2. 發佈性能場景

CMS GC 回收失敗,內存沒法被釋放,應用宕機。

問題定位:

GC回收比例爲默認值68%,OLD區內存1024M,那麼回收的臨界值爲1024*0.68=696.32M。系統的JVM內存佔用爲500M,掃描策略相關的內存爲120M,在切換的過程當中,依賴額外的120M,所以只有在可用內存大於740M時才能正常回收。

解決方案:

調整JVM參數,擴大GC回收比例。

後續技術方案改造,使用增量發佈解決此問題。

3. 掃描過程當中發佈性能場景

問題定位:

掃描平臺發佈流程,當首次請求進來時執行腳本動態編譯過程,因爲腳本較多,所以全部腳本的動態編譯時間較長,在此過程當中,進來的全部請求都會被hand住,形成大量超時

解決方案:

把腳本的動態編譯提早到首次請求調用進來以前,編譯經過後再切換掃描引擎,保證首次請求進來前一切準備就緒。

三:性能測試的執行和結果收集

3.1性能測試的執行

性能測試的執行須要具有如下幾個條件:施壓工具,測試環境以及對測試結果的收集工具。

3.1.1 施壓工具

咱們先來講說施壓工具,支付寶使用的主流施壓工具是開源工具Apache JMeter,支持不少類型的性能測試:

  • Web - HTTP, HTTPS
  • SOAP
  • Database via JDBC
  • LDAP
  • JMS
  • 任何用java語言編寫的接口,均可二次開發並調用。

支付寶大部分接口是webservice接口,基於soap協議,且都是java開發,因此使用jmeter很是方便,即便jemter工具自己沒有自帶支持的協議,也能夠經過開發插件的方式支持。

3.1.2測試環境

測試環境包括被壓機和施壓機環境,須要進行硬件配置和軟件版本確認,保證系統乾淨,無其餘進程干擾,最好能提早監控半小時到1小時,確認系統各項指標都無異常。

另外除了被壓機和施壓機,有可能應用系統還依賴其餘的系統,因此咱們須要明確服務器的數量和架構,1是方便咱們分析壓力的流程,幫助後面定位和分析瓶頸,2是因爲咱們線下搭建的環境越接近線上,測試結果越準確。可是一般因爲測試資源緊張或者須要依賴外圍,例如銀行的環境,就會比較麻煩,一般咱們會選擇適當的進行環境mock。固然,Mock的時候儘可能和真實環境保持一致,舉個簡單的例子,若是支付寶端系統和銀行進行通訊,線上銀行的平均處理時間爲100ms,那麼若是咱們在線下性能測試時須要mock銀行的返回,須要加入100ms延遲,這樣才能比較接近真實的環境。

另外除了測試環境,還有依賴的測試數據也須要重點關注,數據須要關注總量和類型,例如支付寶作交易時,db中流水萬級和億級的性能確定是不同的;還有db是否分庫分表,須要保證數據分佈的均衡性。通常考慮到線下準備數據的時長,通常性能測試要求和線上的數據保持一個數量級。

3.1.3 測試結果收集工具

測試結果收集主要包括如下幾個指標:

響應時間、tps、錯誤率、cpu、load、IO、系統內存、jvm(java虛擬內存)。

其中響應時間、tps和業務錯誤率經過jemter能夠收集。

Cpu、load、io和系統內存能夠經過nmon或linux自帶命令的方式來監控。

Jvm能夠經過jdk自帶的jconsole或者jvisualvm來監控。

整體來講,監控了這些指標,對系統的性能就有了掌握,一樣這樣指標也能夠反饋系統的瓶頸所在。

四.性能測試瓶頸挖掘與分析

咱們在上面一章中拿到性能測試結果,這麼多數據,怎麼去分析系統的瓶頸在哪裏呢,通常是按照這樣的思路,先看業務指標:響應時間、業務錯誤率、和tps是否知足目標。

若是其中有一個有異常,能夠先排除施壓機和外圍依賴系統是否有瓶頸,若是沒有,關注網絡、db的性能和鏈接數,最後關注系統自己的指標:

  1. 硬件:磁盤是否寫滿、內存是否夠用、cpu的利用率、平均load值
  2. 軟件:操做系統版本、jdk版本、jboss容器以及應用依賴的其餘軟件版本
  3. Jvm內存管理和回收是否合理
  4. 應用程序自己代碼

先看下圖:是通常性能測試環境部署圖

1.

咱們在定位的時候,可按照標註中的一、二、3數字依次進行排查,先排查施壓機是否有瓶頸、接着看後端依賴系統、db、網絡等,最後看被壓機自己,例如響應時間逐漸變慢,通常來講是外圍依賴的系統出現的瓶頸致使總體響應變慢。下面針對應用系統自己作下詳細的分析,針對常見問題舉1~2個例子:

4.1 應用系統自己的瓶頸

1. 應用系統負載分析:

服務器負載瓶頸常常表現爲,服務器受到的併發壓力比較低的狀況下,服務器的資源使用率比預期要高,甚至高不少。致使服務器處理能力嚴重降低,最終有可能致使服務器宕機。實際性能測試工做中,常常會用如下三類資源指標斷定是否存在服務器負載瓶頸:

  • CPU使用率
  • 內存使用率
  • Load

    通常cup的使用率應低於50%,若是太高有可能程序的算法耗費太多cpu,或者某些代碼塊進行不合理的佔用。Load值儘可能保持在cpuS+2 或者cpuS*2,其中cpu和load通常與併發數成正比(以下圖)

  • 內存能夠經過2種方式來查看:

    1) 當vmstat命令輸出的si和so值顯示爲非0值,則表示剩餘可支配的物理內存已經嚴重不足,須要經過與磁盤交換內容來保持系統的穩定;因爲磁盤處理的速度遠遠小於內存,此時就會出現嚴重的性能降低;si和so的值越大,表示性能瓶頸越嚴重。

    2) 用工具監控內存的使用狀況,若是出現下圖的增加趨勢(used曲線呈線性增加),有可能系統內存佔滿的狀況:

    若是出現內存佔用一直上升的趨勢,有可能系統一直在建立新的線程,舊的線程沒有銷燬;或者應用申請了堆外內存,一直沒有回收致使內存一直增加。

4.2 Jvm瓶頸分析

4.2.1Gc頻率分析

對於java應用來講,太高的GC頻率也會在很大程度上下降應用的性能。即便採用了併發收集的策略,GC產生的停頓時間積累起來也是不可忽略的,特別是出現cmsgc失敗,致使fullgc時的場景。下面舉幾個例子進行說明:

1. Cmsgc頻率太高,當在一段較短的時間區間內,cmsGC值超出預料的大,那麼說明該JAVA應用在處理對象的策略上存在着一些問題,即過多過快地建立了長壽命週期的對象,是須要改進的。或者old區大小分配或者回收比例設置得不合理,致使cms頻繁觸發,下面看一張gc監控圖(藍色線表明cmsgc)

由圖看出:cmsGC很是頻繁,後經分析是由於jvm參數-XX:CMSInitiatingOccupancyFraction設置爲15,比例過小致使cms比較頻繁,這樣能夠擴大cmsgc佔old區的比例,下降cms頻率注。

調優後的圖以下:

2. fullgc頻繁觸發

當採用cms併發回收算法,當cmsgc回收失敗時會致使fullgc:

由上圖能夠看出fullgc的耗時很是長,在6~7s左右,這樣會嚴重影響應用的響應時間。經分析是由於cms比例過大,回收頻率較慢致使,調優方式:調小cms的回比例,儘早觸發cmsgc,避免觸發fullgc。調優後回收狀況以下

能夠看出cmsgc時間縮短了不少,優化後能夠大大提升。從上面2個例子看出cms比例不是絕對的,須要根據應用的具體狀況來看,好比應用建立的對象存活週期長,且對象較大,能夠適當提升cms的回收比例。

3. 疑似內存泄露,先看下圖

分析:每次cmsgc沒有回收乾淨,old區呈上升趨勢,疑似內存泄露

最終有可能致使OOM,這種狀況就須要dump內存進行分析:

  • 找到oom內存dump文件,具體的文件配置在jvm參數裏:
    -XX:HeapDumpPath=/home/admin/logs 
    -XX:ErrorFile=/home/admin/logs/hs_err_pid%p.log
  • 藉助工具:MAT,分析內存最大的對象。具體工具的使用這裏就再也不介紹。
相關文章
相關標籤/搜索