告白成不成心里沒數,系統扛不扛得住還沒數嗎?!
情人節又來了,這一天的 IT 程序員常常成為被調侃的對象。事實上,性格內向的他們在向心儀的對象告白時,也確實會因為不善言辭,被搞得心里七上八下。
俗話說得好,術(po)業(guan)有(po)專(shuai)攻(ba),告白成不成功心里沒數兒,系統扛不扛得住,你心里怎么還能沒點兒 Balance !
常言道,「沒過十五都是年」。在 2 月 14 日這一天,我們來想象一下中國的傳統節日——春節。
你所在的業務線要上線一個活動:過年七天,用戶每天簽到、邀請好友、完成設定任務都可以得到紅包。這個紅包系統的建設由你來負責,包括所有與紅包相關的功能,比如發紅包、搶紅包、拆紅包等。需求方告訴你活動上線后,對紅包系統調用的 QPS 是 5000。
- 面對每秒 5000 次的請求,你的系統是否可以穩定運行?
- 如果現在要同時上線 10 個活動都需要調用紅包系統,你設計的系統又是否能扛住這 10 個活動的流量?
- 如果宕掉一臺服務器會怎么樣?
- 多長時間能夠恢復?
- 如果扛不住,加多少資源合理?
面對這一連串的問題,你心里有數嗎?
為什么需要關注性能測試?
對于用戶來說,穩定、平穩的使用體驗非常重要。在系統架構階段,對于部分關鍵功能進行性能、容量、安全、可擴展性和穩定性等的評估非常必要。但我們常常缺少這個階段的性能測試實踐,等系統開發結束后才進行,常常為時已晚。
這好比是選拔長跑運動員,在選拔運動員前我們就要知道需要考察哪些素質,比如身體協調性、耐力、沖刺爆發力等等,綜合評估能否應對大賽的考驗。對系統的考察也是如此,在線運行時是否穩定,沒有內存泄漏、線程安全等問題,應對突發大流量系統是否可以平穩度過,系統各類資源參數設置是否合理,該如何設置,參考的標準是什么。
概括來說,性能測試就是驗證系統的爆發力、耐力、協調性,幫助定位問題,為性能不斷優化指導方向。
完整的性能測試該如何進行
之前和其他公司的測試同學討論時,問到他們的性能測試方案,有人說我們用 Loadrunner,有人說我們用 Jmeter。我的感覺是,測試工具一定是必要的,但性能測試一定不能和 Loadrunner、JMeter 劃「=」,而是需要一個完整的測試流程。
下面,我結合馬蜂窩大交通火車票搶票壓測流程,來說說在我看來,整個性能測試應該包括哪些內容。我自己也處于性能測試的摸索階段,如果有不妥之處,還請各位不吝賜教。
圖1:大交通火車票壓測項目流程圖
一、準備階段
1. 什么情況下需要進行性能測試
生產環境下可能出現各種場景,哪些場景下我們需要考進行性能測試?
服務的例行迭代
你所負責系統增加新功能需求,增加了新的業務代碼,新增加代碼有沒有引入性能問題,以上次性能測試結果為參考對本次迭代版本進行壓測,檢查性能是否下降。
服務重構
核心搜索、交易線服務架構進行了重構或者調整,要與重構前服務性能狀況進行對比檢查服務的處理能力是否達到重構目標。
容量規劃
生產環境需要進行容量規劃以支撐更大流量或者新服務上線明確需要多少資源,比如幾臺服務器,Redis 容量是多少。舉個例子,有一個服務 A 的 QPS 是 100,服務 A 每次請求都要對 Redis 進行一次讀和寫,Redis 的 QPS 是 700,原來服務 A 有 3 臺服務器,高峰期流量是 300,生產環境沒有出現資源不夠用的情況。現在上線了一個活動,高峰期流量增長到 600,需要增加多少臺服務器合適呢?上面的例子中根據單機 QPS 在增加 4 臺服務器,可以應對高峰期流量嗎?
有經驗的同學會回答只是增加服務器個數還不夠,因為每個請求對 Redis 有兩次操作,高峰期 600 QPS 映射到 Redis 是 1200,按照 Redis 處理能力 700 QPS,顯然增加機器后雖然服務 A 此時不是瓶頸,但是 Redis 的處理能力仍是瓶頸。
所以,容量規劃的資源是否合理,進行容量規劃時給各類資源的參考值是多少,都需要通過性能測試來給出。
服務支持上層多方業務交易應用
越是支撐各類業務的底層服務,對穩定性、系統吞吐要求越高,就像我們在開篇舉例的紅包系統,這樣的服務在架構設計時需要充分的考慮并發處理能力,是否可以方便的進行系統的容量和性能擴展。
當然,需要性能測試的場景不僅局限于以上列舉的部分,我只列舉出一些,供大家參考和發散思維。
2. 組建測試團隊
雖然在圖 1 的角色中沒有體現運維和 DBA 以及跨部門人員,很多時候,尤其是在生產環境做壓測,都需要這些人員的參與,開發準備好軟件版本由運維同學進行部署,同時需要提前知會其他上下游依賴部門,關注服務,共同配合。
3. 預先分析
為了對系統性能建立直觀上的認識和分析,應對系統較重要和常用的業務場景模塊有針對性地進行分析,以對接下來的測試方案設計進行準備。
二、設計測試方案
在整個性能測試過程中,制定合理有效的性能測試方案很重要。壓測方案中需要明確的內容,我的總結如下圖:
圖2:壓測方案設計思維
1. 性能指標
性能指標是進行壓測的目標,一般這個指標由業務需求方產品經理或項目經理給出,如果產品經理或項目經理不能提供具體數值,如何估算出一個能夠支持業務流量 QPS 值呢?提供幾個參考思考方式:
1)對于活動促銷類的方案,可以參考去年同期活動高峰流量上升百分比,今年同期峰值也上升相同的百分比或者在這個基礎上在增加一定的余量;
2)利用「二八原則」,根據預期到達的 PV 值進行推算,80% 的請求集中在 20% 的時間,那么峰值時間每秒請求數 (QPS)=(總 PV 數 * 80% ) / (每天秒數 * 20% )
3)參考同類型業務最近一個季度甚至一年高峰期QPS 值;
2. 測試準備
測試內容
這里主要分為兩部分,一部分是模擬請求的接口參數,另外是模擬商品(如果產品是外部供應商提供可能需求進行 mock)或者外部依賴服務產生的數據。
壓測數據
- 數據類型:一是接口請求所需數據,如 10w 用戶賬號、100w 訂單;二是壓測所需產品數據準備;
- 代碼上增加針對壓測數據過濾的邏輯,主要為了方便的進行數據隔離和壓測結束環境恢復;
- 有一些外部依賴不能參與壓測(可能會產生費用或影響其他業務方),需要添加模擬的請求返回
壓測資源
比如服務器,用到的中間件、數據庫等。
這里,我想重點說一下為什么要進行數據隔離:
1)區分壓測流量與真實流量,方便壓測結束后進行數據清洗。壓測結束后產生的交易、支付都要進行撤銷,以免產生資損,落到數據庫中數據也要刪除。所以,將壓測流量產生的數據落到影子庫,可以方便進行這些操作,如果沒有影子庫,也可以通過對壓測數據打標簽,來進行分區。
2)壓測數據隱藏,如果測試環境壓測可以不考慮這個問題,生產環境壓測產生的交易對客戶不可見,包括為了進行壓測準備的商品,對客戶也要隱藏。
3)防止壓測產生請求數據進入報表統計。
以在火車票搶票壓測為例,處理的方式是對 UID 進行路由,壓測 UID 產生的請求數據路由到影子庫中,真實請求的 UID 數據存在測試環境數據庫(壓測是在線下壓測環境進行的)。
綜上,結合火車票搶票壓測示例來看,我們在壓測前了做了如下準備:
- 火車票搶票服務依賴其他服務,創建訂單時,對依賴部分做 mock;
- 創單數據同步訂單中心也是做了 mock;
- 準備用與創單的用戶 uid;
- 將從cookie中獲取登陸狀態的代碼剝離,脫離對登錄的依賴,接口本身支持傳 uid 就可以創建訂單
圖3: 火車票搶票壓測服務拓撲
3. 構建壓測模型
壓測模型是模擬用戶行為壓測場景,每個接口請求參數有什么特殊要求,一個場景中會同時有多個接口,這些接口的流量如何配比,后面壓測執行時都按照這樣的場景進行。那如何分析用戶的行為模式獲取到接口的流量配比,下面給出 2 種參考方法:
1)對于已經上線的系統,采用系統日志或輔助的監控系統獲得這些信息。大交通每個業務都接入了 CAT 系統,通過在 CAT 上查看每個 URL 的請求量,
得出壓測場景中涉及到不同接口流量配比。
2)對于未上線的全新系系統,可以參考行業類似系統做分析,或公司類似業務做分析。
4. 編寫壓測腳本
按照用例描述,選擇工具進行編寫。對壓測腳本的編寫,現在有很多成熟的工具,比如 JMeter、nGrinder。火車票搶票壓測工具選用了 JMeter。
三、壓測執行
壓測過程需要開發、運維同學參與,整個壓測執行過程分兩部分:一個部分是啟動壓測腳本對服務器產生請求壓力;一部分是監控服務表現是否符合要求。壓測過程中通常關注的內容有:
- CPU 使用率,通常要求 CPU 使用率<70%;
- 內存使用情況,是否存在內容泄漏;
- 系統業務完整性,返回結果是否正確;
- 系統響應時間是否滿足業務要求;
- 系統處理能力是否穩定,QPS 的大小在固定很小范圍內抖動比如,如果有規律的出現 QPS 值跌落,則鏈路上可能存在某個服務處理比較慢;
- 觀察服務是否存在 ERROR/WARN 級別的報錯;
- 觀察服務 GC 的頻率;
- 壓測結束后占用的資源是否正常釋放;
- 調整服務器數量看系統性能是否具備橫向擴展的能力;
此外還有磁盤 IO、網絡帶寬等……
四、問題優化
壓測目的是就是找出系統潛在的問題及系統各類資源參數設置,壓測問題調優不同業務系統有不同解決方案,開發可能更有發言權,此處不贅述。列舉一些常見的方法:
- 數據庫進行讀寫分離,單條寫改成批量寫;
- 不屬于關鍵鏈路上的服務不做重試或改為異步方式;
- 壓測過程中報 connect: cannot assign requested address
原因:客戶端端口不夠,修改 sysctl.conf 文件配置
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_timestamps=1
net.ipv4.ip_local_port_range = 1024 65535
- 通信的短鏈接改成長連接;
五、記錄壓測報告,分析結果
壓測結束輸出壓測報告,分析不同壓測情況下測試結果找到拐點,得出系統處理能力,得出各類資源參數設置參考值。
一些建議
除了加機器,你還能做什么?
生產環境下,我們會遇到各種各樣的問題。有時,即使進行了充分的性能測試,還是會出現問題。那么對于提高系統穩定性,除了加機器,我們還有哪些方案呢?這里,給大家一些建議:
1)上線提前設計好限流方案,如:
- 活動入口的時候增加游戲環節進行消峰操作,還有秒殺前的倒計時也可以起到流量削峰;
- 在接口層面拒絕多余的訪問, 或者讓多余的訪問排隊等待服務;
2)降級服務,下線一些輔助功能,減少資源的競爭;
3)引入緩沖機制;
4)實時監控訪問量,一旦 QPS 超過預設的閾值,則可以考慮進行擴容以避免出現訪問量過大宕機。
路漫漫其修遠兮,系統的穩定性也是如此,通過不斷的解決問題積累經驗,以應對日益增長的業務需求。
本文作者:董敏,馬蜂窩大交通研發團隊測試工程師,目前主要負責火車票相關業務的測試工作。
【本文是51CTO專欄作者馬蜂窩技術的原創文章,作者微信公眾號馬蜂窩技術(ID:mfwtech)】