背景:一個接口,本身有一定的邏輯,但是不復雜,主要是處理數據,不涉及到數據庫操作,但是內部調用兩個接口。基本邏輯是先調用BI的一個接口獲取到基礎數據,在本地處理完數據在根據classid去業務系統查班級,查完的數據在本地處理,返回結果。其中業務系統的接口是老接口,不會存在性能問題,BI的接口是我先壓測的,也沒性能問題,而本地並無復雜操作,所以接口理論上是不會有性能問題的,但壓測的結果卻很慢。
壓測過程中查看了可以看的地方,沒看到異常(其實有,當時沒看到),而且涉及到三個系統,沒頭緒的話查起來會很浪費時間,於是找開發把主要邏輯加上了時間戳。
結果如下,這是grep出時間最長的。

代碼如下,主要都是redis的操作,進去看邏輯。

邏輯:

不一一看了,這個方法里面主要是對redis的操作,涉及到4個get和4個set,redis的性能是非常好的,之前測試一個4C的服務器,tps輕松上萬,單個get或者set只有幾毫秒。所以說這里不應該這么慢。看上面的時間都已經幾百多毫秒。所以要看下redis的問題,找到redis配置,如下,這是spring boot 對redis連接池的配置,而且開發應該用的默認配置,明顯很小,改大之后再測試。


結果如下,時間明顯少了很多,服務器CPU也已經上去,tps由一百多到達了四百多。問題確定。

回過頭來再看這個問題,可以明顯的感覺到做性能測會代碼的重要性,很多問題,在代碼層很容易定位,至少很容易縮小范圍。
再來看看不用代碼怎么定位問題。下面這段是我打印的兩次線程信息,1.txt是第一次,2.txt是第二次的線程信息,明顯看到第一次中waiting有136個線程,而第二個只有61個

查看具體線程信息,明顯可以看出來是在等待redis線程池。

再看下這個對比,就更明顯了。第二次已經沒有等待redis連接池的線程了。

