任何事情不要一廂情願地希望順利,凡事要正面解讀、逆向思考 ———— 聖嚴法師。
單數月份25日,是統一發票開獎的日子,我們可以在很多發票相關的系統或App裡,看到各種對獎方案,能不能夠在獎號與中獎名單公布後,快速比對完成並通知用戶對獎結果,這件事看起來簡單,但要做好其實有很多細節,更能從中看出每家廠商的技術能力,今天,歷經多次調整,剛好一個系統通過幾十萬中獎用戶的承受能力認證,我們應景來談談一般SQA不容易遇到的場景。
之所以拿聖嚴法師這句話開頭,主要是不小心翻到,覺得第一句話非常像是這個專案裡的開發團隊,非常樂觀的團隊,經歷多次跌倒還是能夠正向思考,精神可嘉,只要有了專業協助,他們肯定可以走的更遠。
自殺式DDoS
這次的例子是發票對獎,讓我們來看這個問題是怎麼發生的。
產品經理看到用戶每次開獎後,都需要自己上來App點擊對獎後,才知道自己有沒有中獎,所以他告訴開發團隊,希望可以讓用戶第一時間可以知道自己的發票中獎了,開獎後,要推送消息給有中獎的用戶,用戶點擊後跳到App開獎畫面,這個時候用戶不用再點擊一次對獎,就能看到中獎結果,這是一個非常不錯的產品需求洞察。
因為本來用戶的發票與中獎資訊就是放在資料庫裡,用戶使用上一直都正常,後端工程師也沒有多想,在後台計算完中獎資訊後,就一起推送消息給用戶,然後,大部分收到消息的用戶就集中在那短短的一兩個小時,順著產品經理的設想,連上來系統看自己的中獎資訊,接著,就沒有然後了。。。
用戶在接下來那一天,一直沒辦法連上這個服務,就如果我們前面說的,工程師設計了一個機制,讓所有的用戶在相對短的時間內,都連上伺服器去看自己中獎情況,再加上沒有先準備好,第一波用戶就直接打掛自己的伺服器了。
最後怎麼解掉這個問題是我們另外的專業服務內容 —— 軟體架構設計,容我放在另外一篇再來談,這篇還是談從QA的角度應該怎麼發現跟驗證系統容量是否符合期待。
壓力(Stress)測試與容量(Volume)測試
先提一件事,就是我找不到好的Volume Test翻譯,他原意取的是大量而不是容量,他雖然也有容量的意思,但在語意上,他是要測試承載大量請求的能力,但真的是找不到合適的名詞,所以我還是沿用一些前輩用的容量測試當作翻譯。
很多初學者因為對定義的不熟悉,往往在學習過程中,會認為這兩種測試其實講的是同一件事,但為什麼在專業軟體測試當中,會把這兩個詞分開呢?那為什麼在現在很多應用場景中,我們只能聽到壓力測試呢?
我們先回到大部分SQA課程中對這兩者的定義來看。
壓力測試專門指系統或程式在資源不足的情況下,正常運作與處理錯誤的能力驗證方式。
容量測試專門指系統或程式在處理"大量"的請求時,是否能正常運作或處理錯誤的驗證方式,這裡裡的大量有可能是單次大處理量,像是大檔案或是能形成大工作量的請求,也有可能是短時間內大量湧入的小處理量請求。
這其實不難理解為什麼大家習慣性混用這兩種測試型態,在大量用戶端請求下,資源耗盡,所以這就算是壓力測試,的確,大部分開發團隊都是這麼理解的,但如果這麼簡單,為什麼要分開定義呢?為了方便解釋,這篇我們專注討論單次大量的場景,單次大處理量的請求,我們找機會再介紹。
簡單地說,這兩種測試看的視角不同,壓力測試其實需要SQA對系統運作的每一個細節都清楚,才能開的出來,譬如說,大部分的SQA不會知道load balancer驅動的擴容策略,也不知道生產環境log的處理方式與rotation policies,更不會知道像是cache mechanism跟cache slot size(or count)這種可以觸達系統極限的條件,更好玩的是,其實大部分開發者也不熟悉,所以在原始碼裡也沒有對應的容錯機制,這很正常,這種連資深工程師都很少遇到的情況,正常開發流程裡,沒人提,你根本就不知道還有這種事,就算真的發生,大部分工程師的處理方式也很簡單粗暴,滿的就清掉或多買點空間,資源不夠就加機器,只有少部分有技術堅持的團隊,會要求把這些細節做到位,這也是為什麼很多系統驗收或上線前都是正常,一上線就會掛掉。
又扯遠了。。。我們繼續說容量測試,這種是從外部視角,根據用戶的核心流程,去模擬大量用戶(或請求)同時進到系統時,能不能維持"體面“?這裡只要服務能持續,能穩定地滿足設計容量內的用戶,讓其他用戶等待,或是稍後再試,基本上就算是及格,如果能在這樣情況下,短時間內擴容並承接著這些設計容量以外的用戶,當然最好,不過這相當考驗DevOps or SRE的能力,通常要發生個幾次事件並諮詢有經驗的前輩才會知道該如何處理。
壓力測試的誤區
回到這篇的主題,這種利用短時間大量請求來測試系統是否能正常運作的方式,有個非常關鍵的設計條件,就是你必須走過"核心流程"的每個系統交互環節才成生效,說的白話一點,就是要能完全模擬出來用戶使用中的每一個環節,這看起來很簡單,但其實大部分團隊在所謂的"壓力測試"裡,沒有測試到想測試的情況,就是因為忽略"每一個環節"這件事,我們底下就介紹三種常見的誤區,以及大家可以自己檢查的方法。
以偏概全
誤區說明:把壓力測試簡化為發送大量請求,但實際只跑到部分 API 呼叫或單純的首頁瀏覽,沒有涵蓋完整使用者經驗(如登入、查詢、交易、登出等互動流程)。
結果:測出的系統瓶頸偏差,核心流程未被測到 —— 很容易錯過真正的崩潰點。
檢查:萃取核心流程中的條件節點,針對大部分用戶會走進的條件分支進行確認。
一葉障目
誤區說明:許多團隊在同一網段、同一雲服務供應商內,以多台甚至單台實例集中執行壓力測試腳本,但這其實僅測出該環境內節點或同網段的出口效能。
結果:看起來測試的總量很多,但是遇到同樣的量,一樣掛了。
檢查:設定同時承受請求數的單位與時長,並設定對應的監控方式,以實際接收的單位時間量為準去驗證。
不識廬山真面目
誤區說明:在 UAT/DEV 或與正式環境不同的架構測試壓力,或用等比例的方式去預估壓力。
結果:雖然該做的都做到了,但是生產環境還是扛不住。
檢查:不要為了省短期的驗證費用(這個真的是驗完就可以關了),就假設在這些相似甚至是完全不同架構的環境裡可以有一樣的表現,一定要盡量做到高度一致或相似,基於這個原則再去想怎麼省測試費用。
知道了,下一步?
前面講的有點太技術性,來點可操作性比較強的管理方式。
如果你是甲方,在乙方提出的測試計劃裡,確認壓力測試的方案是按照場景的預期使用量來設計,並且在驗收報告裡,應該有場景中每個路徑節點,在測試過程中承受壓力的統計數據,只要最終結果符合你對使用量的期待,基本上就算過關了。
如果你是產品開發團隊,照著customer journey map去追壓力測試的路徑是最直接的方式,但如果團隊本來沒有,用GA4(或其他behavior tracking platform)的行為路徑,或後端API requests distribution去追也是可以嘗試的方向,主要是技術團隊能知道這些資料的順序與代表性即可。
看完還是不知道該怎麼做?
最近收到些信跟消息,說自己看完文章還是不知道該怎麼做,問我能不能開課授業,或去他們公司直接評估,其實像本文提到的內容,台灣大部分團隊遇到的機會也不高,大部分都是客戶說了算,驗收過就過了,如果有自己開發產品的準備,或是遇到多次內部提案後還是無法解決,再找我們不遲。