壓力測試性能問題分析

開始性能測試前須要瞭解的內容:
  一、項目具體需求。
  二、指標:響應時間在多少之內,併發數多少,tps多少,總tps多少,穩定性交易總量多少,事務成功率,交易波動範圍,穩定運行時長,資源利用率,測哪些交易,哪些接口,測試哪些場景。
  三、環境:生產環境服務器數量,測試環境服務器數量,按照資源配比得出測試指標。
  四、協議:系統用什麼協議進行通信。
  五、壓力機數量:若是併發用戶數太多,須要把壓力發到不一樣的壓力機,否則可能會存在壓力機瓶頸問題,致使tps和響應時間抖動。
  六、交易佔比:分析線上日誌得出tps佔比。
  七、系統架構:請求流通過哪些環節,壓測時監控這些環節。
   測試:
  一、基準:一個用戶迭代100次,關注響應時間,事務成功率100%。
  二、負載:10個用戶跑10分鐘,關注響應時間,事務成功率100%。
  三、容量:估算一個總tps,根據公式計算出每一個交易的pacing和vu,獲取系統最大處理能力(最優容量),再令外測出三個梯度做爲對比(兩組小於最優容量,一組大於最優容量),四組容量VU等差,tps等差,對比每組容量實際佔比和測試佔比(越接近越能模擬真實場景),關注響應時間,總tps,tps,事務成功率,AP cpu利用率,DB cpu利用率,線程死鎖, 數據庫死鎖。
  其中響應時間應小於負載測試時間,總tps應約等於預估總tps(相差不超過10是正常的),每一個交易的tps應接近預估總tps*佔比,事務成功率100%,AP cpu小於60%,DB cpu小於80%。dump線程棧檢測是否有線程死鎖,查看數據庫日誌看是否有數據庫死鎖。
  四、穩定性:採起最優容量的80%做爲壓力持續運行24小時,觀察系統長時間運行的性能表現,關注響應時間,tps,總tps,事務成功率,交易總數,觀察是否有內存溢出(堆溢出,棧溢出,持久代溢出),cpu利用率是否達標,mem是否不持續增加,是否能正常觸發fullgc,gc時間,gc頻率, fullgc時間,fullgc頻率(重點關注,JVM調優就是爲了減小fullgc頻率)。
   監控:
  容量測試和穩定性測試時啓動nmon監控。
  壓測中遇到的性能問題及解決辦法:
   1、容量測試過程當中cpu太高
  一、用vmstat實時監控cpu使用狀況。很小的壓力AP cpu卻到了80%多,指標是不能超過60%。
  二、分析是use cpu太高仍是sys cpu太高,常見的是use cpu使用太高。
  三、若是是sys cpu使用太高,先把消耗cpu最多的進程找出來(top命令),再找到該線程下消耗cpu太高的是哪幾個線程,再把該線程轉換成16進制,再用jstack命令來dump線程棧,看這個線程棧在調用什麼東西致使use cpu太高。
   2、內存溢出(堆溢出、棧溢出、持久代溢出)
  一、堆內存溢出
  1)穩定性壓測一段時間後,LR報錯,日誌報 java.lang.OutOfMemoryError.Java heap space。
  2)用jmap -histo pid命令dump堆內存使用狀況,查看堆內存排名前20個對象,看是否有本身應用程序的方法,從最高的查起,若是有則檢查該方法是什麼緣由形成堆內存溢出。
  3)若是前20裏沒有本身的方法,則用jmap -dump來dump堆內存,在用MAT分析dump下來的堆內存,分析導出內存溢出的方法。
  4)若是應用程序的方法沒有問題,則須要修改JVM參數,修改xms,xmx,調整堆內存參數,通常是增長堆內存。
  二、棧內存溢出
  1)穩定性壓測一段時間後,LR報錯,日誌報Java.Lang.StackOverflowError。
  2)修改jvm參數,將xss參數改大,增長棧內存。
  3)棧溢出必定是作批量操做引發的,減小批處理數據量。
  三、持久代溢出
  1)穩定性壓測必定時間後,日誌報Java.Lang.OutOfMenoryError.PermGen Space。
  2)這種緣由是因爲類、方法描述、字段描述、常量池、訪問修飾符等一些靜態變量太多,將持久代佔滿致使持久代溢出。
  3)修改jvm配置,將XX:MaxPermSize=256參數調大。儘可能減小靜態變量。
   3、線程死鎖
  一、容量測試壓測一段時間後,LR報鏈接超時。
  二、形成這種現象的緣由不少,好比帶寬不夠,中間件線程池不夠用,數據庫鏈接池不夠,鏈接數佔滿等都會形成鏈接不上而報超時錯誤。
  三、jstack命令dump線程棧,搜索線程棧裏有沒有block,若是有的話就是線程死鎖,找到死鎖的線程,分析對應的代碼。
   4、數據庫死鎖
  一、容量測試壓測一段時間後,LR報鏈接超時。
  二、形成這種現象的緣由不少,好比帶寬不夠,中間件線程池不夠用,數據庫鏈接池不夠,鏈接數佔滿等都會形成鏈接不上而報超時錯誤。
  三、數據庫日誌中搜索block,能搜到block的話就是存在數據庫死鎖,找到日誌,查看對應的sql,優化形成死鎖的sql。
   5、數據庫鏈接池不釋放
  一、容量測試壓測一段時間後,LR報鏈接超時。
  二、形成這種現象的緣由不少,好比帶寬不夠,中間件線程池不夠用,數據庫鏈接池不夠,鏈接數佔滿等都會形成鏈接不上而報超時錯誤。
  三、去數據庫查看應用程序到數據庫的鏈接有多少個( show full processlist),假如應用程序裏面配置的數據庫鏈接爲30,在數據庫查看應用程序到數據庫的鏈接也是30,則表示鏈接池佔滿了。將配置改爲90試試,去數據庫看若是鏈接到了90,則能夠肯定是數據庫鏈接池不釋放致使的。查看代碼,數據庫鏈接部分是否是有建立鏈接可是沒有關閉鏈接的狀況。基本就是這種狀況致使的,修改代碼便可。
   6、TPS上不去
  一、壓力大的時候tps頻繁抖動,致使總tps上不去。查看是否有fullgc(tail -f gc_mSrv1.log | grep full)。
  二、pacing設置過小也會致使tps上不去,對抖動大的交易多增長點用戶便可。
  三、tps抖動,單壓抖動大的交易,發現很平穩,這時懷疑是否是壓力太大致使,因此發容量的時候把壓力最大的那隻交易分到其餘壓力機,而後發現tps不抖動了。注意:多臺壓力機隻影響tps抖動,不會影響服務器的cpu。
  四、看響應時間有沒有超時,看用戶數夠不夠。
   7、服務器壓力不均衡(相差1%-2%是正常的)
  一、跑最優容量的時候,四臺AP只有一臺cpu超過60%,其餘三臺都在60%如下。
  二、查看服務器是否有定時任務。
  三、查看是否存在壓力機瓶頸。
  四、是否存在帶寬瓶頸(局域網不存在此問題)。
  五、查看部署的版本,配置是否同樣。
  六、可能別人也在用這些AP,由於同一臺物理機上有不少虛擬機,由於別人先用,資源被別人先佔了。
   8、fullgc時間太長
  一、跑容量和穩定性的時候,出現LR報請求超時錯誤,查看後臺日誌是fullgc了,看LR幾點報的錯和日誌裏fullgc的時間是否對應,fullgc會暫停整個應用程序,致使LR前端沒響應,因此報錯,這時能夠減小old代內存,從而減小fullgc時間,減小fullgc時間LR就不會報錯,讓用戶幾乎感受不到應用程序暫停。
  二、四臺AP輪流着full gc(部分 server fullgc,其餘server也會fullgc),這時能夠制定策略讓不一樣的server不一樣時fullgc,或者等夜間交易量少時寫定時任務重啓服務。
  注意:
  服務器日誌爲error下測試。
  服務啓動後幾分鐘內發壓壓力會很大,最好是服務啓動兩三分鐘後再開始跑壓力。