負(fù)載測(cè)試的端到端指南
譯文【51CTO.com快譯】眾所周知,功能性測(cè)試通常著眼于單個(gè)用戶對(duì)于目標(biāo)應(yīng)用程序的基本使用體驗(yàn)。而對(duì)成百上千的用戶同時(shí)訪問(wèn)目標(biāo)站點(diǎn)的場(chǎng)景,特別是那些面向公眾服務(wù)的Web應(yīng)用,開發(fā)人員勢(shì)必需要在應(yīng)用上線之前,模擬真實(shí)的并發(fā)訪問(wèn)情況,并通過(guò)考慮和進(jìn)行負(fù)載測(cè)試,為任何可能發(fā)生的問(wèn)題與意外,做好充分的準(zhǔn)備。
在本指南中,我將通過(guò)如下四個(gè)階段,向您介紹負(fù)載測(cè)試過(guò)程中的相關(guān)知識(shí)。
- 計(jì)劃:為何要測(cè)試?測(cè)試什么?
- 編寫測(cè)試腳本:如何測(cè)試?
- 執(zhí)行:針對(duì)應(yīng)用程序運(yùn)行測(cè)試腳本。
- 分析和報(bào)告:發(fā)現(xiàn)了什么?需要修復(fù)什么?
計(jì)劃負(fù)載測(cè)試
在計(jì)劃階段,團(tuán)隊(duì)會(huì)聚到一起,討論并確定包括目標(biāo)、范圍、所需資源、以及測(cè)試場(chǎng)景等方面的內(nèi)容。此階段的可交付成果為測(cè)試計(jì)劃。不過(guò),它在形式上是否正式,則取決于團(tuán)隊(duì)的實(shí)際要求。值得注意的是,任何測(cè)試計(jì)劃都是一項(xiàng)團(tuán)隊(duì)活動(dòng),我們需要從所有利益相關(guān)者(即:參與測(cè)試或可能受測(cè)試影響的任何人)處獲取建議。
要求
我們需要搞清楚為什么要做負(fù)載測(cè)試?該問(wèn)題看似簡(jiǎn)單,但是不同的利益相關(guān)者可能會(huì)給出不同的測(cè)試場(chǎng)景需求。因此為了達(dá)成一致,我們最好將負(fù)載測(cè)試的目標(biāo)表述為非功能性的需求 (nonfunctional requirements,NFR),以便定義應(yīng)用程序的期望狀態(tài),并且能夠包括由團(tuán)隊(duì)決定的性能閾值。例如:基于響應(yīng)時(shí)間的要求,已注冊(cè)的用戶登錄用時(shí)不應(yīng)超過(guò)3秒(即達(dá)到90%的響應(yīng)時(shí)間)。可見,好的需求往往能夠滿足:SMART(具體的Specific、可衡量的Measurable、已商定的Agreed Upon、可實(shí)現(xiàn)的Realistic、以及及時(shí)的Timely)等特點(diǎn)。而且在實(shí)踐中,我們可以從如下方面進(jìn)行把控。
范圍
約定了負(fù)載測(cè)試的共同目標(biāo),我們不但可以縮小待測(cè)內(nèi)容的領(lǐng)域,還能確保每個(gè)成員都清楚有哪些部分不需要被測(cè)試。
先決條件
在開展測(cè)試之前,我們需要考慮包括:參與的人數(shù)、執(zhí)行測(cè)試所需的時(shí)間、以及測(cè)試數(shù)據(jù)的環(huán)境要求等多方面的資源與先決條件。雖然我們并不總是需要一個(gè)單獨(dú)的測(cè)試環(huán)境,來(lái)進(jìn)行負(fù)載測(cè)試,但是如果需要的話,應(yīng)該事先知會(huì)DevOps等團(tuán)隊(duì)。
負(fù)載建模
負(fù)載模型可以被用來(lái)描述模擬負(fù)載的一組特征。例如:用戶最常訪問(wèn)的是哪些頁(yè)面、哪個(gè)服務(wù)部分、最長(zhǎng)訪問(wèn)的時(shí)段與地理位置等方面。您可以將這些因素植入測(cè)試腳本中,以更加真實(shí)地模擬出,可能對(duì)應(yīng)用程序產(chǎn)生的流量和影響。
服務(wù)器監(jiān)控
在測(cè)試過(guò)程中,我們往往需要通過(guò)腳本,來(lái)監(jiān)控后臺(tái)服務(wù)器上各類警報(bào)與日志。如果您的負(fù)載測(cè)試工具檢測(cè)到明顯的性能下降,則需要能夠通過(guò)關(guān)聯(lián)服務(wù)器上的相應(yīng)信息,來(lái)予以勘察。不過(guò),值得注意的是,任何類型的監(jiān)控都會(huì)增加現(xiàn)有服務(wù)資源的開銷,因此整個(gè)團(tuán)隊(duì)?wèi)?yīng)事先確定好需要監(jiān)控和跟蹤的指標(biāo)與信息。
測(cè)試場(chǎng)景
待測(cè)試和模擬的場(chǎng)景設(shè)定,往往能夠協(xié)助我們更加準(zhǔn)確地獲取網(wǎng)站與應(yīng)用的真實(shí)性能。例如:我們既可以創(chuàng)建一個(gè)典型工作日的負(fù)載配置文件,又可以模擬大促時(shí)的峰值負(fù)載配置文件,還可以模擬某個(gè)生產(chǎn)出現(xiàn)中斷時(shí)的場(chǎng)景。不同的測(cè)試場(chǎng)景能夠?yàn)槲覀儾杉降闹T如:持續(xù)時(shí)間、并發(fā)用戶數(shù)、請(qǐng)求數(shù)、激增周期(即:應(yīng)用從0個(gè)用戶上升到最大用戶量的速度)、以及“峰谷”負(fù)載(即:在整個(gè)測(cè)試過(guò)程中,每秒請(qǐng)求數(shù)的波動(dòng))等,可供分析的參數(shù)數(shù)據(jù)。
在設(shè)計(jì)負(fù)載測(cè)試計(jì)劃時(shí),您既可以包含多條用戶故事線,又可以使用各種Trello卡片(譯者注:一種卡片式任務(wù)管理工具)。工具的輸出格式并不重要;重要的是每個(gè)成員都能夠從中解讀出一致性、規(guī)范化的測(cè)試結(jié)果。
編寫測(cè)試腳本
有了在前面計(jì)劃階段的各項(xiàng)準(zhǔn)備,現(xiàn)在我們便可以開始通過(guò)編寫負(fù)載測(cè)試腳本,來(lái)為測(cè)試的實(shí)施做好準(zhǔn)備了。
工具的選擇
目前,市場(chǎng)上有著許多負(fù)載測(cè)試類工具。出于對(duì)各種在用工具、以及財(cái)務(wù)和供應(yīng)商等方面的考量,我們不一定可以自由地按需選擇負(fù)載測(cè)試工具,但是如下方面還是值得我們認(rèn)真考慮的:
資源和成本
- 整體購(gòu)置的價(jià)格,及其定價(jià)模型是否允許用戶按需增減使用量?
- 實(shí)際需要自行構(gòu)建,還是應(yīng)當(dāng)購(gòu)買端到端的負(fù)載測(cè)試方案?
- 團(tuán)隊(duì)擁有哪些技術(shù)技能與工具經(jīng)驗(yàn)?誰(shuí)將負(fù)責(zé)進(jìn)行測(cè)試?
特點(diǎn)
- 負(fù)載測(cè)試工具是否能夠支持應(yīng)用程序所使用的協(xié)議和技術(shù)?
- 測(cè)試工具與對(duì)應(yīng)腳本語(yǔ)言的學(xué)習(xí)曲線是否“陡峭”?
- 測(cè)試工具是否可以讓多人輕松地協(xié)作,并處理同一個(gè)腳本?
- 能否與測(cè)試棧中的其他可用于測(cè)試管理、測(cè)試結(jié)果分析、服務(wù)器監(jiān)控、團(tuán)隊(duì)溝通等工具相集成?
- 測(cè)試工具能否被添加到CI/CD管道中?
- 該工具是否通過(guò)提供簡(jiǎn)單的方法,來(lái)設(shè)置性能閾值或服務(wù)等級(jí)目標(biāo)(SLO)?
- 測(cè)試結(jié)果能否顯示在可用的報(bào)告中,以及能否與現(xiàn)有的數(shù)據(jù)可視化工具相集成?
支持
- 如果出現(xiàn)問(wèn)題,客戶支持是否需要通過(guò)額外付費(fèi)才能獲取?
- 在線幫助文檔是否夠用?
- 是否擁有經(jīng)驗(yàn)分享的用戶社區(qū)?
擴(kuò)展負(fù)載測(cè)試
- 單個(gè)負(fù)載生成器每秒可模擬多少個(gè)虛擬用戶或請(qǐng)求?
- 能否處理由測(cè)試所產(chǎn)生的大數(shù)據(jù)量?
- 能否根據(jù)用戶的位置特征,從不同的地理位置實(shí)施測(cè)試?
- 是否允許用戶從云端生成負(fù)載?
鑒于上述需求,我選定k6(https://k6.io/)作為開發(fā)負(fù)載測(cè)試腳本的工具。總的說(shuō)來(lái),k6有著如下三方面的優(yōu)勢(shì):
- 由于它是開源的,因此任何人都可以下載該工具,并親自試用其腳本。
- 由于是用JavaScript編寫而成,因此那些使用過(guò)Cypress、Puppeteer或Playwright等工具的前端開發(fā)人員、或測(cè)試人員都能夠輕松地上手。
- 由于它能夠在一臺(tái)機(jī)器上生成上萬(wàn)個(gè)用戶的并發(fā)數(shù),因此即便在負(fù)載增加的情況下,它也具有一定的成本效益。
當(dāng)然,下面將要討論到的各個(gè)步驟也適用于其他工具。而且,我強(qiáng)烈建議您使用多種工具,自行進(jìn)行概念驗(yàn)證,以找到最適合特定情況和測(cè)試場(chǎng)景的工具。
安裝和設(shè)置
如果您使用的是Mac系統(tǒng),那么便可以使用Brew來(lái)輕松地安裝k6,即:從終端處運(yùn)行--brew install k6,就能夠在幾秒鐘之內(nèi)搞定。當(dāng)然,如果您使用的是其他操作系統(tǒng)的話,請(qǐng)通過(guò)鏈接--https://k6.io/docs/getting-started/installation/,來(lái)獲取詳細(xì)的安裝說(shuō)明。
一個(gè)基本的k6測(cè)試腳本
如下JavaScript代碼段展示了最基本的k6測(cè)試腳本:
- import http from ‘k6/http’;
- export default function () {
- let response = http.get(‘https://test.k6.io’);
- }
該腳本會(huì)向一個(gè)簡(jiǎn)單的測(cè)試站點(diǎn)(其URL為https://test.k6.io)發(fā)送一個(gè)HTTP的GET請(qǐng)求。請(qǐng)將該代碼復(fù)制到文本編輯器中,并存為test.js文件。接著,您便可以使用命令--k6run test.js,來(lái)運(yùn)行它,并得到如下顯示結(jié)果:
在k6中運(yùn)行簡(jiǎn)單的本地測(cè)試示例
從上述截圖中,我們可以看出,本地主器上的1個(gè)虛擬用戶執(zhí)行了1次腳本的迭代。而該HTTP測(cè)試請(qǐng)求的響應(yīng)時(shí)間為128.2毫秒(即:http_req_duration)。
使測(cè)試腳本更加真實(shí)
顯然,上述腳本的GET請(qǐng)求過(guò)于簡(jiǎn)單,無(wú)法達(dá)到用負(fù)載測(cè)試腳本在數(shù)量、以及地理分布上模擬真實(shí)用戶的訪問(wèn)情況。而如果負(fù)載測(cè)試腳本不夠真實(shí),則會(huì)在測(cè)試期間產(chǎn)生誤報(bào),甚至無(wú)法讓用戶發(fā)現(xiàn)應(yīng)用組件潛在的性能問(wèn)題。下面,我們來(lái)討論一下如何讓測(cè)試腳本更為真實(shí)。
添加靜態(tài)資源
如果頁(yè)面上帶有可被瀏覽器自動(dòng)檢索到的圖像或腳本等靜態(tài)資源,那么請(qǐng)確保測(cè)試腳本也會(huì)去檢索此類資源。畢竟它們會(huì)影響到您獲得頁(yè)面的響應(yīng)時(shí)間。當(dāng)然,如果您已經(jīng)獲得了來(lái)自第三方提供商的許可,那么您也可以考慮從第三方處獲取靜態(tài)資源。
設(shè)置緩存和cookie行為
雖然站點(diǎn)的首次訪問(wèn)者無(wú)法調(diào)用本地的緩存資源,但是重復(fù)訪問(wèn)者則會(huì)從緩存中檢索相應(yīng)的資源。對(duì)此,我們應(yīng)當(dāng)檢查負(fù)載測(cè)試工具的默認(rèn)緩存和cookie管理的設(shè)置,并通過(guò)按需更改,來(lái)匹配真實(shí)的測(cè)試場(chǎng)景。
添加“思考時(shí)間”
真正的用戶通常不會(huì)不停地反復(fù)刷新相同的URL。他們?cè)趯?dǎo)航到目標(biāo)網(wǎng)站后,會(huì)花一些時(shí)間閱讀頁(yè)面上的內(nèi)容,與頁(yè)面上的某些組件進(jìn)行交互。這些用戶的“思考”時(shí)間其實(shí)就是各個(gè)請(qǐng)求之間的延遲。因此,通過(guò)添加1到5秒的“思考時(shí)間”,我們可以讓應(yīng)用服務(wù)器免于遭受外掛機(jī)器人發(fā)出的請(qǐng)求轟炸。
使用不同的用戶路徑
用戶路徑是指用戶如何與應(yīng)用程序進(jìn)行交互的流程,其中包括:他們會(huì)訪問(wèn)哪些頁(yè)面,輸入哪些信息等。我們前面在計(jì)劃階段所建立的工作負(fù)載模型,可以直接反映出系統(tǒng)中最常見的用戶流程,例如:使用不同的瀏覽器進(jìn)行登錄,或是從購(gòu)物車中選擇商品付款等。在k6中,我們可以通過(guò)添加不同的場(chǎng)景來(lái)實(shí)現(xiàn),而其他工具則可能稱之為線程組或執(zhí)行組。
添加測(cè)試數(shù)據(jù)
正如普通用戶是不會(huì)一遍又一遍地搜索相同的關(guān)鍵字,也不會(huì)使用同一個(gè)測(cè)試帳戶在各處同時(shí)登錄那樣,我們的測(cè)試腳本也不應(yīng)該重復(fù)地使用相同的數(shù)據(jù)。如果多個(gè)虛擬用戶使用同一帳戶進(jìn)行登錄,那么就可能導(dǎo)致其響應(yīng)被緩存,進(jìn)而縮短響應(yīng)的時(shí)間,或增加錯(cuò)誤率。對(duì)此,您需要將腳本修改為從某個(gè)CSV文件中獲取測(cè)試數(shù)據(jù),以增加真實(shí)的隨機(jī)性。
設(shè)置測(cè)試參數(shù)
測(cè)試參數(shù)往往能夠通過(guò)調(diào)整測(cè)試用戶數(shù)的激增與驟降,來(lái)改變用戶負(fù)載的時(shí)間變化趨勢(shì),進(jìn)而協(xié)助您繪制出虛擬用戶數(shù)與時(shí)間變化的曲線圖表。
在k6中體現(xiàn)的負(fù)載測(cè)試期間虛擬用戶的數(shù)量變化
設(shè)置失敗的判定標(biāo)準(zhǔn)
模擬真實(shí)用戶的一個(gè)重要環(huán)節(jié)便是發(fā)現(xiàn)有哪些因素會(huì)導(dǎo)致用戶訪問(wèn)的失敗。您可以通過(guò)添加響應(yīng)驗(yàn)證、檢查和閾值(包括響應(yīng)時(shí)間或錯(cuò)誤率的閾值),將失敗的判定標(biāo)準(zhǔn)添加到測(cè)試腳本中。同時(shí),您也可以根據(jù)實(shí)際情況,靈活地調(diào)整這些與性能相關(guān)的標(biāo)準(zhǔn)。
根據(jù)上述討論的要點(diǎn),我對(duì)最初的k6基本腳本進(jìn)行了修改,讓它更貼近真實(shí)的測(cè)試情況。在參考鏈接--https://gist.github.com/nicolevanderhoeven/fb74cd9769c8abf95eeb8765a49398cb中,也包含了一個(gè)帶有登錄憑據(jù)的CSV文件。
執(zhí)行負(fù)載測(cè)試
讓我們延用上面的k6腳本,并通過(guò)執(zhí)行如下命令,來(lái)觸發(fā)負(fù)載測(cè)試的運(yùn)行:
- k6 run test.js
該命令將根據(jù)文件中已有的測(cè)試參數(shù)在本地執(zhí)行k6腳本。此類小型驗(yàn)證性測(cè)試,通常被稱為震蕩測(cè)試(shakeout tests)。當(dāng)然,我們接下來(lái)會(huì)在基礎(chǔ)架構(gòu)上運(yùn)行更加復(fù)雜的負(fù)載測(cè)試。
測(cè)試的真實(shí)性
當(dāng)您在數(shù)據(jù)中心的主機(jī)上運(yùn)行負(fù)載測(cè)試時(shí),由于測(cè)試與應(yīng)用服務(wù)器同屬一個(gè)網(wǎng)絡(luò),其響應(yīng)時(shí)間會(huì)比用戶真實(shí)體驗(yàn)到的要快得多。因此,我們應(yīng)當(dāng)設(shè)法將負(fù)載生成器的位置,與用戶的物理位置相匹配。對(duì)此,在云端運(yùn)行測(cè)試便是一種增加測(cè)試真實(shí)性的簡(jiǎn)便方法,尤其是當(dāng)您的大多數(shù)最終用戶是在組織外部的時(shí)候。
針對(duì)上述例子,您可以通過(guò)鏈接--https://app.k6.io/account/register,注冊(cè)一個(gè)k6的云端帳戶(其中,前50個(gè)測(cè)試是免費(fèi)的)。由于k6本身是開源的,因此您也可以在自己的云端基礎(chǔ)設(shè)施上運(yùn)行它。當(dāng)然原生的k6云服務(wù)會(huì)更加直接且便于上手。
在擁有了帳戶之后,您可以通過(guò)鏈接--https://app.k6.io/account/api-token,復(fù)制API令牌,然后在終端中運(yùn)行如下命令,以授權(quán)本地的k6運(yùn)行您的帳戶:
- k6 login cloud –token
而成功地通過(guò)了身份驗(yàn)證之后,您便可以選擇在云端運(yùn)行如下命令了:
- k6 cloud test.js
下圖展示了k6執(zhí)行的負(fù)載測(cè)試結(jié)果。圖中的執(zhí)行模式(execution)則表明您是在云端運(yùn)行該測(cè)試的。
由于您的測(cè)試默認(rèn)會(huì)在美國(guó)Ashburn區(qū)域的k6 AWS賬戶中運(yùn)行,因此您可以使用云端執(zhí)行選項(xiàng)(cloud execution options,請(qǐng)參見--https://k6.io/docs/cloud/creating-and-running-a-test/cloud-tests-from-the-cli#cloud-execution-options),將此設(shè)置按虛擬用戶的比例,指定到其他區(qū)域。
分析負(fù)載測(cè)試的結(jié)果和報(bào)告
盡管我們?cè)谶壿嬌蠒?huì)將分析流程與執(zhí)行步驟相互分離,但是兩者實(shí)際上是重疊的。也就是說(shuō),上述k6的輸出截圖中其實(shí)已經(jīng)包含了指向k6云端儀表板的鏈接,可方便我們?cè)跍y(cè)試運(yùn)行過(guò)程中,實(shí)時(shí)地查看到測(cè)試的結(jié)果。這種實(shí)時(shí)監(jiān)控的測(cè)試方式可以讓用戶在出現(xiàn)問(wèn)題時(shí),及時(shí)地發(fā)現(xiàn)問(wèn)題,并在必要時(shí)中止測(cè)試,以對(duì)其進(jìn)行修復(fù)。如果測(cè)試是由多個(gè)負(fù)載生成器來(lái)執(zhí)行的,那么k6會(huì)有一個(gè)統(tǒng)一的儀表板,以展示測(cè)試的整體概況。
在k6Cloud中執(zhí)行負(fù)載測(cè)試后的結(jié)果示例
如果出現(xiàn)大量的錯(cuò)誤,或者是響應(yīng)時(shí)間明確地表明某個(gè)組件無(wú)法處理負(fù)載的情況,我們應(yīng)當(dāng)立即中止測(cè)試,獲取必要的信息,以針對(duì)出現(xiàn)的瓶頸提出性能改進(jìn)和解決方案。當(dāng)然,k6也會(huì)幫助用戶創(chuàng)建指向儀表板的可共享式鏈接(請(qǐng)參見--https://app.k6.io/runs/public/f6ad87cec7a24a8c82e46c816e67c4b3),以方便相關(guān)團(tuán)隊(duì)通過(guò)協(xié)同“會(huì)診”,發(fā)掘出測(cè)試數(shù)據(jù)背后的真實(shí)原因。
雖然這些帶有測(cè)試結(jié)果的共享儀表板足以滿足敏捷團(tuán)隊(duì),但是對(duì)于某些項(xiàng)目而言,則可能需要正式的測(cè)試記錄總結(jié)報(bào)告。畢竟,負(fù)載測(cè)試的目的并不在于測(cè)試本身,而是對(duì)于結(jié)果的處理。我們需要向利益相關(guān)者清楚地傳達(dá)測(cè)試結(jié)果,以便大家更為有效地解決各種性能問(wèn)題。
原文標(biāo)題:An End-to-End Guide to Load Testing,作者: Nicole van der Hoeven
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】