網站平常跑得好好的,活動檔期一開、電子報一發,流量瞬間湧進來,頁面卻開始轉圈、回應變慢,最後整站丟出 502。事後檢討往往得到同一個結論:沒有人事先知道這台主機到底扛得住多少人同時上線。主機壓力測試就是用來回答這個問題的方法,它在真正的大流量來臨前,先用模擬流量把網站推到極限,找出承載上限與第一個會壞掉的環節。
這篇文章會把兩條主流路線一次講清楚:給站長與行銷人員用、零程式碼的 Loader.io,以及給開發者與維運人員用、能寫腳本模擬複雜情境的 k6。從測試前的準備、實際操作、結果判讀,到測出問題後該先優化哪裡,整條流程走一遍,讓你不只會跑測試,還看得懂數字背後在說什麼。
主機壓力測試是什麼,跟網站速度測試差在哪
主機壓力測試是對伺服器施加超過日常水準的流量,觀察它在什麼負載下開始變慢、開始回傳錯誤,最後在哪個點完全失去回應。目的不是把網站弄壞,而是在可控的情況下找出那條臨界線,這樣才知道現在的主機規格還剩多少餘裕。
很多人會把它跟網站速度測試混為一談,兩者其實看的是完全不同的東西。速度測試(例如 PageSpeed 那一類工具)量的是「單一使用者」打開頁面的載入體驗,回答的是「我這個頁面快不快」。壓力測試量的是「一群人同時湧入」時系統的穩定度,回答的是「同時來 500 人、800 人時,這台主機還撐得住嗎」。
打個比方,速度測試像是看一個人跑百米的成績,壓力測試則是看一群人同時擠進同一道門時,門框會不會被擠垮。一個網站可以單人載入很快,卻在百人同時在線時就崩潰,因為瓶頸常常不在前端,而在伺服器的 CPU、記憶體、資料庫連線數這些共用資源上。兩種測試都該做,但要解決「大流量撐不住」的問題,只能靠壓力測試。
壓力測試、負載測試、尖峰測試與浸泡測試的差別
開始動手前,先分清楚四種測試類型,因為它們對應的設定參數與要回答的問題都不一樣。這四種測試用的是同一套工具、同一台主機,差別在於你怎麼安排流量的進場方式。
測日常尖峰
測崩潰臨界
測瞬間暴衝
測長時間穩定
四種測試的定位整理如下:
| 測試類型 | 英文 | 流量進場方式 | 要回答的問題 |
|---|---|---|---|
| 負載測試 | Load Testing | 模擬預期的正常尖峰人數 | 日常高峰時回應時間還在可接受範圍嗎 |
| 壓力測試 | Stress Testing | 流量慢慢加碼到超出預期 | 主機在多少人時開始撐不住 |
| 尖峰測試 | Spike Testing | 短時間從零暴衝到極高 | 突發流量(搶購、爆紅)來時能否頂住 |
| 浸泡測試 | Soak Testing | 中等負載維持數小時 | 長時間運作會不會記憶體外洩、越跑越慢 |
對多數電商與內容網站來說,最常用的是負載測試與尖峰測試。負載測試確認你規劃的活動人數主機接得住;尖峰測試模擬電子報一發、KOL 一貼文那種瞬間湧入的場景。壓力測試則用來標出絕對上限,浸泡測試比較進階,通常是排查「網站開久了會越來越慢」這類疑難雜症時才會跑。
壓測前要先準備的三件事,避免把線上站測壞
動手之前先處理好三件事,否則很容易把正在營運的網站測到當機,反而傷到真實使用者。壓力測試的本質就是對伺服器發送大量請求,這件事必須在受控的前提下進行。
第一、只測自己有權限的網站。 不論 Loader.io 還是 k6,都不該拿去打別人的網站,那等同於發動小規模阻斷服務攻擊。Loader.io 在測試前強制要求所有權驗證,方式是下載一個 TXT 檔上傳到網站根目錄,或設定一筆 DNS 紀錄,驗證通過才能對該網域發送流量。
第二、挑離峰時段、最好先在測試環境跑。 把壓測排在凌晨等低流量時段,避免測試流量跟真實訪客搶資源。如果條件允許,先複製一份網站到測試環境(staging)測,確認流程沒問題、抓到大致的承載範圍後,再對正式站做一次較溫和的驗證。共享主機尤其要小心,因為你的瞬間流量可能影響同一台機器上的其他網站,部分主機商的服務條款甚至禁止未告知的壓測,事前確認一下比較保險。
第三、先記下目前的基準值。 在沒有任何模擬流量的狀態下,先量一次首頁與關鍵頁面的回應時間(也就是 TTFB,瀏覽器送出請求到收到第一個位元組的時間)。這個基準值是後面判讀的對照組,沒有它,你只會看到一堆數字卻不知道哪個算正常、哪個算惡化。
用 Loader.io 做無程式碼壓力測試的完整流程
如果你不想碰指令列,Loader.io 是門檻最低的選擇,註冊完幾分鐘就能開測,不需要安裝任何軟體,免費方案最多可模擬到一萬個並行連線。流程大致分成註冊、新增目標、驗證、設定測試、判讀五步。
註冊後先到「Target hosts」頁面新增要測的網域,只要填純網域(例如 example.com),不用加 http 或 https,除非你用了非標準的連接埠才要補上去。接著完成前面提到的所有權驗證,畫面顯示驗證通過後就能建立第一個測試。
Loader.io 的關鍵在於三種測試模式,選錯模式會讓你誤判承載力:
- Clients per test:設定整段測試期間的「連線總數」,工具會平均分配。例如 20 秒內產生 2000 個連線,等於每秒約 100 個。每個連線完成請求後就斷開,適合模擬「使用者開頁、讀完、離開」的情境,數據通常比較好看。
- Clients per second:直接指定「每秒幾個連線」。設定每秒 1000 個、測 20 秒,效果等同 Clients per test 模式下總共 20000 個連線。這個模式最貼近「每秒請求數(RPS)」的概念,測 API 端點時特別直覺。
- Maintain client load:指定一個範圍(例如從 0 增加到一萬),連線數逐步累積且每個連線持續保持不斷開。這最接近真實的瀏覽情境,使用者不會開一秒就走,會持續停留、點擊、載入。想知道網站能「同時容納多少人在線」,這是最準確的模式,但測出來的數字也會比前兩種嚴苛得多,因為伺服器資源被持續佔用。
設定好參數按下「Run Test」就開始,也可以先存起來或排程在特定時間自動跑,方便不同時段反覆測試做比較。測試結束後 Loader.io 會把結果寄到信箱,並提供幾個分頁的圖表:Time 分頁畫出每秒連線數與回應時間的關聯曲線,是最重要的一張;Details 分頁列出每秒的 HTTP 狀態碼分佈,看 200 成功與 4xx、5xx 錯誤的比例;Bandwidth 分頁記錄每秒的資料傳輸量,頁面太肥時這裡會偏高。
用 k6 寫腳本做更精細的壓力測試
當你需要模擬登入、結帳這種多步驟流程,或想把壓測接進 CI/CD 自動跑,Loader.io 就不夠用了,這時候輪到 k6。k6 的核心用 Go 寫成,效能很強,依官方說明單一主機便能產生每秒數十萬次請求,而測試腳本則用 JavaScript(ES6)撰寫,對寫過前端的人幾乎沒有學習門檻。
k6 是一支需要安裝的執行檔,Windows 可用 Chocolatey 套件管理器透過 choco install k6 安裝,macOS 可用 Homebrew 的 brew install k6,也支援直接下載官方安裝檔或用 Docker 跑。安裝完後,所有壓測邏輯都寫在一份 .js 腳本裡。最基本的腳本長這樣:
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
http.get('https://your-site.com');
sleep(1);
}
這裡的 export default function 就是每一位虛擬使用者(VU,Virtual User)會反覆執行的內容,sleep(1) 讓每位 VU 每跑完一輪停一秒,模擬真人讀頁的停頓。直接下 k6 run script.js 會用一位 VU 跑一次;要正式壓測,可以在指令加參數,例如 k6 run --vus 10 --duration 30s script.js,意思是用 10 位虛擬使用者持續打 30 秒。
更精細的做法是把情境寫進腳本的 options,用 stages 做漸進加壓與降壓(也就是 ramp up 與 ramp down),更貼近真實流量的起伏:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 20 }, // 30 秒內從 0 爬到 20 VU
{ duration: '1m30s', target: 20 }, // 維持 20 VU 撐 90 秒
{ duration: '20s', target: 0 }, // 20 秒內降回 0,結束
],
};
export default function () {
const res = http.get('https://your-site.com');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}
check 函式會驗證每個回應是不是預期狀態(這裡檢查是否為 200),但它不會中斷測試,只會在結果裡回報通過的百分比,讓你看出在多大壓力下開始出現失敗回應。
k6 跑完會在終端機印出一整排指標,重點幾個要會看:http_req_duration 是整個 HTTP 請求的往返時間,其中的 http_req_waiting 就是俗稱的 TTFB;http_req_failed 是失敗率;http_reqs 是總請求數;vus 與 vus_max 是當下與最大的虛擬使用者數。判讀的核心是看 VU 往上加的過程中,http_req_duration 何時開始飆高、http_req_failed 何時開始大於零,那個轉折點就是主機的承載上限。
怎麼從測試結果判讀主機真正的承載上限
不論用哪個工具,判讀的邏輯都一樣:盯住「並行人數(或 RPS)」與「回應時間、錯誤率」這兩組數字的關係,找出曲線轉彎的那個點。承載上限不是某個漂亮的整數,而是「回應時間開始明顯惡化、或錯誤率開始竄升」的那個流量值。
正常的曲線應該是:並行連線往上加的時候,回應時間還維持在跟基準值差不多的水準,錯誤率保持為零。一旦你看到回應時間在某個並行數突然往上彈,或 5xx 錯誤開始大量出現,那個位置就是主機開始撐不住的臨界點。把它記下來,就是你這台主機現階段的安全承載範圍。
回應時間的判讀可以抓幾個概略區間:200ms 以下相當優秀,200 到 500ms 屬於正常,500ms 到 1 秒使用者已經有感,超過 1 秒就明顯影響體驗。但要注意,用 Maintain client load 這種持續佔用連線的模式測出來的回應時間天生就偏高,這不代表網站有問題,是測法本來就嚴苛,重點永遠是「隨流量上升的變化趨勢」而非單一數字。
還有一個常被忽略的細節:線上壓測工具(如 Loader.io)的流量是從它自己的雲端機房發出的,跟你真實訪客的網路環境、地理位置都不同,所以結果是個有參考價值的基準,而不是絕對精準的數值。比較務實的用法是固定用同一套設定,定期重測來追蹤趨勢,看每次優化或升級之後承載上限有沒有往上移。
WooCommerce 與動態頁面壓測要注意的快取陷阱
測 WordPress 內容站跟測 WooCommerce 購物站,難度完全不同,關鍵就在「頁面快取」。一般文章頁可以被整頁快取成靜態 HTML,伺服器幾乎不用運算就回傳,所以壓測首頁、文章頁時,你量到的承載力往往高得漂亮,那其實大半是快取的功勞,不是主機真實的運算能力。
問題在於 WooCommerce 的購物車、結帳、會員中心這類頁面是動態的,含個人化內容,快取外掛預設會把它們排除在快取之外,每一次請求都得實際跑 PHP、查資料庫。也就是說,這些頁面才真正反映主機在高併發下的運算瓶頸。如果你只壓測首頁就以為主機能扛上千人,等到大量使用者同時湧進結帳流程,現實會給你完全不同的數字。
務實的做法是分開測:壓測一組靜態頁(首頁、商品列表)看快取後的上限,再單獨壓測一組會繞過快取的動態頁(用 k6 模擬加入購物車到結帳的多步驟流程,或在 Loader.io 對結帳頁路徑施壓),看真正吃運算資源時的承載力。後者的數字才是規劃活動檔期時該參考的下限。提醒一點,壓測結帳流程只是觀察伺服器能否承受併發請求,這裡談的是主機承載而不是金流串接,實際付款設定屬於另一個主題。
測出承載不足後,先優化哪裡再考慮升級主機
測出承載力不足時,先別急著升級主機方案,很多瓶頸是設定問題,花錢買更大的機器之前,往往有更省的解法可以先做。優化的順序大致從成本最低、效益最高的往下排。
- 開啟頁面快取:這是提升 WordPress 承載力最有效的單一手段。有了頁面快取,伺服器不必每次重新組裝 HTML,直接吐出快取好的靜態頁,能扛的並行數會大幅拉高。
- 加上物件快取:如果裝了很多需要查資料庫的外掛、或跑 WooCommerce,高併發時資料庫常是第一個瓶頸。用 Redis 或 Memcached 做物件快取,可以把重複的查詢結果暫存起來,減輕資料庫負擔。
- 壓縮圖片、改用 WebP:未壓縮的大圖會吃掉大量頻寬,拖慢整體載入。把 JPEG、PNG 轉成 WebP,能在幾乎不犧牲畫質的前提下大幅縮小檔案。
- 掛上 CDN:用 CDN 把靜態資源快取到各地節點,訪客就近載入,同時分攤了主機的連線壓力。Cloudflare 有免費方案,入門門檻很低。
- 升級 PHP 版本:PHP 8.x 的執行效能明顯優於 7.x,光是升級版本就有感,但升級前要先在測試環境確認佈景主題與外掛相容。
把這些都做過、壓測數字還是頂不住預期流量,才是真正該升級主機的時候。不同等級主機的承載差距很大:共享主機適合小型部落格與個人網站,同時在線數通常在數百以內;VPS 主機資源獨享,能撐到上千人,適合中型網站與一般電商;雲端主機具備彈性擴展能力,流量暴增時能自動加資源,適合大型網站與會遇到搶購尖峰的平台。實際數字會因網站複雜度、有沒有用快取、資料庫查詢效率而差很多,但大方向不變:先把設定面榨乾,再用壓測數據去佐證該升級到哪一級,錢才花得有依據。
主機壓力測試的價值,不在跑出一個好看的數字,而在於把「我的網站到底扛得住多少人」從靠運氣的猜測,變成有依據的判斷。先用 Loader.io 花幾分鐘抓出大致的承載範圍,需要模擬登入、結帳這類複雜流程時再用 k6 寫腳本深入,量到臨界點後先從快取、圖片、CDN 這些設定面優化,最後才依數據決定要不要升級主機。下次活動檔期或電子報發送前,先跑一次壓測,看看主機還剩多少餘裕,遠比上線後對著當機畫面手足無措來得從容。