記一次完整的性能測試

項目背景:

想針對某系統的首頁進行性能優化,經埋點在ES裏面分析,未處理訂單通知模塊是導致應用服務器CPU高的主因。

分析:

瞭解到這個模塊是採用的技術是主動輪詢的機制,每小時有500w的請求量,我們分析了主動輪詢的請求裏面,默認設置的30s的輪詢間隔時間,大概會有1500的QPS,這個請求量對服務器的性能是有一定的影響,且分析到這裏面其實有90%的無效請求。

那麼該怎麼樣減少服務端的壓力?

方案1: 繼續使用輪詢的方式,增加資源(服務器,redis,數據庫),繼續保持30s的輪詢間隔時間或者更長的時間。

但方案1有個問題是, 當系統用戶增多以及對消息及時性要求增加時,這種輪詢接口就會給系統造成很大的壓力。且隨着系統使用率的提高,該接口的QPS還會繼續提升。

如果能夠做到後端服務主動將消息推送給客戶端瀏覽器,這樣能夠減少無效請求,且消息能夠及時。這樣會帶來特別大的改善?

有了上面的討論,於是方案2的落地: 採用websocket的方式,實現服務端推送消息。

but,問題又來了,我們的客戶使用的IE版本各不相同,少部分的使用的還是IE低版本瀏覽器,但只有IE10及以上版本才支持websocket。
繼續討論。。我們需要一個屏蔽瀏覽器的且還支持websocket的框架。
於是我們的開發小哥哥們開發了一個將websocket和polling機制以及其它的實時通信方式封裝在一起,做了一個瀏覽器消息實時推送的平臺。且稱爲C平臺吧。 (這個平臺也就是我們的測試範圍啦~~)

畫了個老的模塊的架構圖

待測系統的框架了解:

在前面的項目介紹裏面,其實已經聊到了很多。再理下:
1、瀏覽器調用C平臺建立連接,帶上userid,sid(sid爲業務id)。
2、C平臺告知業務系統用戶連接已經建立推送hermes消息的uid。
3、業務系統通過提供的Client直接調用推送接口,完成推送。
4、C平臺server通過userid的關係將消息推送給瀏覽器端。

下面畫了幾張圖:

瀏覽器端發起連接並註冊消息。


客戶端註冊的示意圖1

訂單寫入hermes隊列


新的示意圖2

hermes消費端job


新的示意圖3

測試需求分析:

瞭解項目的測試範圍後,怎麼來分析測試需求;
本次的調優出發點原本是通過減少首頁未處理訂單的qps,以達到減少服務器的壓力,從而提高服務器的性能。那針對本次的調優思路後,測試重點轉化爲C平臺的性能如何。
再拆分需求:
1.因爲是websocket的連接實現的技術,那麼C平臺到底能支撐多少的連接呢?是否能滿足系統用戶的需求呢?
2.在已經建立連接後,推送接口的性能如何?佔用系統資源多少?
hermes是不是能夠及時處理這些數據呢?

再轉換爲:

  1. 看C平臺單臺服務器的能支撐客戶端最大是多少?此時C平臺服務器的性能消耗。
    2.獲取推送接口的性能表現
  2. 在建立websocket連接的基礎上,獲取查詢uid接口性能表現。
    4.在2的情況下,hermes是否存在數據積壓。

測試指標分析:

需求清楚之後,測試轉換爲的場景其實就是一個長連接的測試,2個接口的容量測試。

引導開發小哥哥們,我要獲取以下幾個指標:

  1. 單臺服務器需要滿足峯值的長連接數是多少? 服務器資源分別不能超過多少?
  2. 推送接口的數據量是多少? 會推送幾種不同的消息體大小 ?
  3. 查詢uid的接口,按最大uid多少進行?
  4. job支持最大的並行處理能力是多少?

測試場景:

指標獲取後,就是測試場景, 三個負載及兩個容量測試:一個長連接的測試,後面2個接口的容量,都是基於建立好長連接後才能開始。
混合場景: 在已經建立好websocket長連接情況下,針對2個接口做混合測試,查看單臺服務器的整體性能表現。

測試腳本:

2個post接口的腳本沒有啥好聊的,在建立好連接的前提下,設置好固定的TPS跑就可以了。
說說第一個建立websocket的,挺有意思的~~
我們要模擬A系統前端和C平臺建立連接, 沒有辦法直接錄製請求,從前面瞭解到是用websocket,只能手寫請求,(當時還沒有jmeter3.2的版本,界面不支持websocket,當時用jmeter3.0,下了一系列的jar放進去。。 )
開始直接打開jmeter加了個websocket的sampler,手寫請求,發送,然後請求一直一直是失敗的。NO.NO.NO!
why?why?why?
於是打開了抓包工具fiddler看前端系統的未處理訂單的請求,看到前面其實還有兩次http的請求。

抓包分析圖

前面2次的http的get操作,第一次要獲取一個id,第二次把第一次獲取的id再http發出去。
然後纔是websocket,纔開始初始化,建立命名空間,建立連接,獲取推送等一系列的操作。

腳本
相關的websocket的jar包

測試執行:

因爲要求的目標連接數比較大,在建立websocket連接的時候,我這裏用了20臺高配的執行機~~~~ (有點想吐槽jmeter本身的性能,捂臉~ )
其他的此處省略一萬字的循環,有問題的可以私我~

測試結果:

具體的結果就不貼出來了,此處也省略一萬字的循環。有問題的可以私我~

整體的優化效果:

具體的監控對比圖就不上了。看看幾個數據:
平臺上線後,QPS從1500 降到了 200.
應用服務器的CPU得到明顯的改善,總體的指標下降50%
對redis服務器的請求,QPS從2500降到了600

總結:

從這次測試來看,很早的參與進來,換個角度站着看性能優化。還是挺有意思的~

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