性能測試tps上不去,又是redis的坑,說多了都是淚啊

前言:這是幾個月前壓測某項目登錄接口時遇到的性能問題,雖然大家不一定會遇到,但是分析定位問題的思路還是可以參考一下。

1、壓測過程中,tps突然劇烈下降,且所有請求失敗(下圖綠線)

在這裏插入圖片描述

服務端錯誤日誌,獲取不到redis連接池(Could not get a resource from the pool),另外,從下圖可以看到,當前jedis版本是2.9.1

在這裏插入圖片描述

獲取不到連接,可能是這四種情況:
  Timeout waiting for idle object
  Pool exhausted
  Unable to activate object
  Unable to validate object

下圖,表示等待空閒連接超時

在這裏插入圖片描述

2、jedis的連接池就是用commons-pool2來管理的,使用jvisualvm打開對應的應用進程,根據上圖的提示,找到org.apache.commons.pool2

在這裏插入圖片描述

可以看到相關的配置

在這裏插入圖片描述

活動連接1000,連接滿了

在這裏插入圖片描述

dump堆內存進行分析(此時壓測已經停止)

在這裏插入圖片描述

根據文章開頭的日誌信息,搜索org.apache.commons.pool2.impl,然後雙擊下面的DefaultPooledObject類

在這裏插入圖片描述

進入實例

在這裏插入圖片描述

實例狀態是ALLOCATED

在這裏插入圖片描述

ALLOCATED表示在使用中,壓測結束後,雖然連接釋放了,但是資源沒歸還

在這裏插入圖片描述

下面可以看到,dataSource爲空

在這裏插入圖片描述

如果dataSource爲空,就走else,說明只關閉了連接,資源沒歸還到隊列中,後面的線程就獲取不到空閒連接

在這裏插入圖片描述

可以看到,實例有很多

在這裏插入圖片描述

爲什麼會出現這種情況呢?
通過查看源碼及官網,可以確定,這是2.9.1的bug,改爲2.9.0就沒報錯了。
官網:https://github.com/xetorthio/jedis/pull/1918/commits/df1bffa3c77f4ede4c912f2c3e78b5c8857725e7

在這裏插入圖片描述

在這裏插入圖片描述

Move dataSource reset before connection returned to pool.

If datasource reset after the connection returned to pool, it might reset the datasource after it was allocated to another thread

意思是:在連接返回到池之前重置移動數據源。
如果數據源在連接返回到池之後重置,那麼它可能會在將數據源分配給另一個線程之後重置該數據源

3、出現很多實例狀態是ALLOCATED,dataSource爲null的原因:

在多線程時,如果dataSource在連接釋放後重置(根據代碼邏輯可知:連接釋放前,資源已經歸還,但是未重置),可能在重置前,這個dataSource已經分配給另外一個線程了,此時重置,就把已經獲取了這個dataSource的線程的dataSource重置了,這樣就導致很多狀態是ALLOCATED、dataSource值爲null的實例,進而這些線程都只關閉了連接,而沒有歸還資源,最終導致獲取不到連接,即文章開頭的異常日誌信息,這也印證了都是壓測一段時間後纔開始報錯的現象。

另外,有些性能問題,還是需要一定的代碼能力,而且,測試會代碼是個趨勢。

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