壓測中遇到的服務器端性能問題及解決辦法

1 應用cpu過高

  1、用vmstat實時監控cpu使用情況。很小的壓力AP cpu卻到了80%多,指標是不能超過80%,有可能CPU在進行大量計算;
  2、分析是user cpu過高還是sys cpu過高,常見的是user cpu使用過高;
  3、如果是user cpu使用過高,先把消耗cpu最多的進程找出來(top命令),再找到該線程下消耗cpu過高的是哪幾個線程,再把該線程轉換成16進制,再用jstack命令來dump線程棧,看這個線程棧在調用什麼東西導致user cpu過高;

2 內存溢出(堆溢出、棧溢出、持久代溢出)
1、堆內存溢出

  產生的現象:穩定性壓測一段時間後,LR報錯,日誌報java.lang.OutOfMemoryError.Java heap space。
  排查手段:
1)用jmap -histo pid命令dump堆內存使用情況,查看堆內存排名前20個對象,看是否有自己應用程序的方法,從最高的查起,如果有則檢查該方法是什麼原因造成堆內存溢出。

  2)如果前20裏沒有自己的方法,則用jmap -dump來dump堆內存,在用MAT分析dump下來的堆內存,分析導出內存溢出的方法。
  解決方式:如果應用程序的方法沒有問題,則需要修改JVM參數,修改xms,xmx,調整堆內存參數,一般是增加堆內存。

2、棧內存溢出
  產生的原因:穩定性壓測一段時間後,LR報錯,日誌報Java.Lang.StackOverflowError。
  解決方式:修改jvm參數,將xss參數改大,增加棧內存。棧溢出一定是做批量操作引起的,減少批處理數據量。

3、持久代溢出

  產生的現象:穩定性壓測一定時間後,日誌報Java.Lang.OutOfMenoryError.PermGen Space。
解決方式:
  1)這種原因是由於類、方法描述、字段描述、常量池、訪問修飾符等一些靜態變量太多,將持久代佔滿導致持久代溢出。
  2)修改jvm配置,將XX:MaxPermSize=256參數調大。儘量減少靜態變量。

3 線程死鎖
  產生的原因:在多線程程序的編寫中,如果不適當的運用同步機制,則有可能造成程序的死鎖,經常表現爲程序的停頓,或者不再響應用戶的請求。
產生的現象:
  1、容量測試壓測一段時間後,LR報連接超時。
  2、造成這種現象的原因很多,比如帶寬不夠,中間件線程池不夠用,數據庫連接池不夠,連接數佔滿等都會造成連接不上而報超時錯誤。
排查手段:
  1、jstack命令dump線程棧,搜索線程棧裏有沒有block,如果有的話就是線程死鎖,找到死鎖的線程,分析對應的代碼。
   jstack -F pid >jts.log(java進程id,可以用jps或者ps aux|grep java 去找),將線程的狀態輸出到jts.log文件

  值得關注的線程狀態有:
  死鎖,Deadlock(重點關注)
  執行中,Runnable
  等待資源,Waiting on condition(重點關注)
  等待獲取監視器,Waiting on monitor entry(重點關注)
  暫停,Suspended
  對象等待中,Object.wait() 或 TIMED_WAITING
  阻塞,Blocked(重點關注)
  停止,Parked

4 數據庫死鎖
  產生的現象:容量測試壓測一段時間後,LR報連接超時。
  排查手段:數據庫日誌中搜索block,能搜到block的話就是存在數據庫死鎖,查看對應的sql,優化造成死鎖的sql。

5 數據庫連接池不釋放
  產生的現象:容量測試壓測一段時間後,LR報連接超時。
  排查與解決方式:去數據庫查看應用程序到數據庫的連接有多少個( show full processlist),假如應用程序裏面配置的數據庫連接爲30,在數據庫查看應用程序到數據庫的連接也是30,則表示連接池佔滿了。將配置改成90試試,去數據庫看如果連接到了90,則可以確定是數據庫連接池不釋放導致的。查看代碼,數據庫連接部分是不是有創建連接但是沒有關閉連接的情況。基本就是這種情況導致的,修改代碼即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章