互聯網常見架構接口壓測性能分析及調優手段建議

互聯網常見架構接口壓測性能分析及調優手段建議

常見的互聯網架構中,一般都能看到spring+mybatis+mysql+redis搭配的身影,在我所服務的公司亦是如此。一般來說,應用內部的接口都是直接調用的,所謂的面向接口編程,應用間的調用直接調或者通過類似dubbo之類的服務框架來執行,數據格式往往採用json,即統一也方便各數據間做轉換和取值,緩存一般使用redis或memcached,存儲一些對象或json格式的字符串。對外提供的接口,一般都需要進行壓力測試,以便估算其性能,併爲後續的調優提供指導方向,以下接口便是在壓測過程中出現的各種“奇怪現象”,所謂奇怪,指的是從表象上看與我們正常的邏輯思路不符,但其本質還是我們對壓力下程序的表現出來的特徵不熟悉,用慣用的知識結構試圖去解釋,這根本是行不通的。下文是我在一次全面壓測過程後對數據進行的分析彙總,其中的現象是很多壓測常見的,裏面的分析過程及改進措施我認爲有很大的參考意義。具體內容如下:(部分接口爲了安全我省略了其名稱,但不影響我們的分析,另外形如1N3T之類的表示的是1臺nginx,3臺tomcat,具體的tps數值只是爲了說明優化前後的比照,沒有實際意義)

 

1        接口名稱: 獲取列表

1.1      壓測現象:單臺tps700多,應用cpu高負載

  1.1.1        問題分析:

    舊框架,平均響應時間長,應用CPU高,程序內部有大量的bean到map到json之間的轉換,修改數據庫連接數後,tps沒有提升。

  1.1.2        改進措施:

    重構系統,用mybatis替代之前的dao操作,減少bean-map-json之間的內部數據轉換,減少程序內部的無用操作。

  1.1.3        改進效果:

    tps改進後能到3000左右,有較大提升,但壓測時應用cpu幾乎跑滿,還有改善空間。

1.2      壓測現象:數據庫資源利用率高

  1.2.1        問題分析:

    單臺應用,數據庫資源cpu都能到50%,10臺tomcat在1萬併發下數據庫cpu跑滿,load值700多,但db的qps也不過11554,並不算多,因此懷疑是sql執行耗費了cpu,可能是某條sql沒有按索引查找或者索引失效。

  1.2.2        改進措施:

    查看SQL文件發現如下sql:select count(1)  from orders where order_status_id !=40 ,將其改爲select order_id from orders  然後通過程序把order_status_id!=40的過濾掉。通過list.size()來獲取。order_status_id即使加了索引,由於是!=比較,所以不會去按索引查找,導致cpu高

  1.2.3        改進效果:

    相同環境下(1臺nginx,10臺tomcat,1000併發),tps由3000變成3727,略有增長,但是db的cpu明顯下降,變爲30%,效果明顯

1.3      壓測現象:1N15T ,tps4552;10N15T,tps9608

  1.3.1        問題分析:

    後端都是15臺tomcat,前端1臺nginx時tps爲4552,通過lvs掛10臺nginx時爲9608,增長不明顯,其nginx和tomcat都壓力不大,集羣結果不合理,懷疑是nginx轉發配置的問題;

  1.3.2        改進措施:

    未進一步改進:可能是需要調整nginx的參數,之前發現過nginx不同的配置對後端集羣環境的tps影響很大

  1.3.3        改進效果:

 

 

2        接口名稱: 信息查詢接口

2.1      壓測現象:單臺tps2000多,應用cpu高,db的qps15000左右

  2.1.1        問題分析:

    舊框架,程序內部有很多Bo-map-json相互的轉換

  2.1.2        改進措施:

    刪除冗餘代碼、更換連接池包,使用mybatis

  2.1.3        改進效果:

    Tps由2000多增長爲8000多,db的qps爲9000左右,優化後壓測應用的cpu佔用高,幾乎跑滿。

 

2.2      壓測現象:數據庫無壓力,應用增加多臺後tps不變

  2.2.1        問題分析:

    1N1T和1N10T的tps一樣,都爲5000,增大併發時錯誤數增多,應用cpu耗費70%,db無壓力,nginx單臺通過ss –s 發現端口占滿,即nginx到tomcat之間轉發的連接端口time-wait狀態6萬多。Nginx存在瓶頸。

  2.2.2        改進措施:

    調優nginx參數,將短連接改爲長連接

  2.2.3        改進效果:

    1N3T的tps能到17376,tomat的cpu壓力84%,db的qps18000,cpu69%,應用的資源基本使用到量。

 

 

3        接口名稱: 獲取詳情

3.1      壓測現象:單臺應用tps2600,10臺tomcat才3700

  3.1.1        問題分析:

  增加應用服務器,tps增長不明顯,且nginx、tomcat、db的負載都不高,說明服務器本身不是瓶頸,考慮是不是網絡的問題,通過監控網卡包流量發現網絡數據跑滿,因爲此接口會有大量數據的輸出,因此瓶頸在網絡上。另外,測試過程中發現redis有報錯,redis服務器是虛機,可能服務能力有限。

  3.1.2        改進措施:

    開啓tomcat的gzip壓縮。

  3.1.3        改進效果:

    同等併發下(1臺nginx,10臺tomcat,1000併發),tps由3727增長到10022,增長了近3倍,效果顯著。

 

3.2      壓測現象:1N10T集羣下nginx參數調優對tps提升效果明顯

  3.2.1        問題分析:

    經過tomcat的啓用gzip後,1N10T下tps爲10022,需進一步提升。

  3.2.2        改進措施:

    優化nginx:

    l  nginx日誌關閉

    l  nginx進程數量worker,由24改爲16

    l  nginx  keepalive數量由256改爲2048

  3.2.3        改進效果:

  Tps由10022提升爲13270。

3.1      壓測現象:1N5T和1N10T的tps相差不大

  3.1.1        問題分析:

    1N10T的tps爲1萬3千多,1N5T的tps爲1萬2千多,相差不大,應用的tomcat資源利用沒滿,cpu爲65%,Db的QPS已經到2萬多了,單臺服務器db基本上到量了,因此再增加應用也沒效果,只會導致響應的時間變長。

  3.1.2        改進措施:

    單臺db已經無法改進了,要不提升服務器硬件,要不讀寫分離。

  3.1.3        改進效果:

 

 

4        接口名稱: 促銷

4.1      壓測現象:通過redis存取數據,tps才1000多,CPU 有壓力

  4.1.1        問題分析:

    此接口通過redis取數據,tps不高才1000多,但cpu佔用了80%,說明程序內部有大量序列化反序列化的操作,可能是json序列化的問題。

  4.1.2        改進措施:

    將net.sf.json改成alibaba的fastjson。

  4.1.3        改進效果:

    同等併發條件下tps由1000多提升爲5000多,提高了近5倍。

  

4.1      壓測現象:參數多時tps下降明顯

  4.1.1        問題分析:

    此接口根據參數從redis中獲取數據,每個參數與redis交互一次,當一組參數時tps5133,五組參數時tps1169,多次交互影響了處理性能。

  4.1.2        改進措施:

    將從redis獲取數據的get改爲mget,減少交互次數。

  4.1.3        改進效果:

    五組參數時1N3T壓測TPS9707,據此估算即使是單臺tomcat,tps也能有三四千,性能比單次get的調用方式提升了3,4倍。

4.2      壓測現象:1N3T tps1萬多,在增大tomcat可能tps增長不會明顯

  4.2.1        問題分析:

    此處說的是可能,因爲nginx服務器的cpu雖然不高,但pps已經800多k,此時應該是nginx的服務器網絡流量成爲了瓶頸。(只是猜測)

  4.2.2        改進措施:

    可以增加多臺nginx負載,前端加lvs

  4.2.3        改進效果:

 

 

5        接口名稱: 追蹤接口

5.1      壓測現象:1N10T的tps低於1N3T的tps

  5.1.1        問題分析:

    1N3T在2000併發下tps爲9849,此時db的qps爲90000,CPU80%,將tomcat增到10臺,5000併發下,tps爲7813,db的qps爲19000,cpu75%,load 1,說明壓力增大情況下db的壓力反而下來了,注意到nginx服務器的網卡流量達到885M,說明是壓力過大情況下,網絡滿了,發生丟包,導致db端壓力反而下來了。

  5.1.2        改進措施:

    注意壓測情況下部分接口由於數據量傳輸較大,會出現網絡瓶頸。

  5.1.3        改進效果:

 

6        接口名稱: 回填接口

6.1      壓測現象:tps不到500,db的qps3500

  6.1.1        問題分析:

    雖然缺少應用的cpu及db的cpu利用率數據,較低的tps應該是應用的瓶頸,且需要關注是不是db在處理查詢的時候緩慢。

  6.1.2        改進措施:

    1.連接池由dbcp改爲hikar;

    2.減少了日誌打印輸出

    3.sql優化,將部分條件過濾改爲在java代碼中執行

  6.1.3        改進效果:

  Tps由不到500增長爲1300多。

7        接口名稱: 券查詢

7.1      壓測現象:集羣結果與單臺應用結果相比不合理

  7.1.1        問題分析:

    查看是否存在瓶頸資源,可以看到5臺tomcat集羣下,tps爲9952,但db的qps爲5-6萬,cpu利用率爲37%,說明對數據庫進行了大量的主鍵或索引查詢,一般單臺db的qps也就4萬左右,再增加應用的集羣數量,對tps也不會有太大影響。

  7.1.2        改進措施:

    可以考慮分庫

  7.1.3        改進效果:

 

8        接口名稱: 推薦

8.1      壓測現象:nginx長短連接差異

  8.1.1        問題分析:

    18nginx,2tomcat時tps8100,此時應用服務器的端口數滿, 一般來說,Nginx短連接在高併發下容易導致端口占滿的問題。

  8.1.2        改進措施:

    將nginx改爲長連接

  8.1.3        改進效果:

    tps增長爲10733,TPS穩定,起伏減少,但是CPU耗盡。說明cpu打滿了,此時如果還要優化就的進行代碼調優了。

9        接口名稱: 查詢2

9.1      壓測現象:18N20T的tps才6842

  9.1.1        問題分析:

    18臺nginx,20臺tomcat,tps才6842,此時應用cpu利用率85%,說明cpu存在瓶頸,但檢查此接口並未做大計算量的工作,有可能是日誌的級別問題,cpu在頻繁的打日誌。

  9.1.2        改進措施:

    將日誌級別由debug級改爲info級

  9.1.3        改進效果:

    同等環境tps由6842增長爲23592.坑爹的生產環境debug日誌級別。

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