<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Locust on Tarragon</title><link>https://tarrragon.github.io/blog/tags/locust/</link><description>Recent content in Locust on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 15 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/locust/index.xml" rel="self" type="application/rss+xml"/><item><title>Locust</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/</guid><description>&lt;p>Locust 的核心責任是用 Python 表達高度自訂的使用者行為與 protocol client。它適合 Python 團隊、需要自訂 client、需要 distributed worker、或 scenario 邏輯比工具內建 sampler 更複雜的壓測流程。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Locust 適合把壓測寫成一般 Python 程式。當 workload model 需要呼叫 internal SDK、特殊 protocol、複雜資料準備、狀態機、隨機行為或自訂 client、Locust 可以直接使用 Python 生態來表達。底層架構是 &lt;em>master + worker&lt;/em> 分散式 swarm、worker 之間用 Gevent green-thread（非 OS thread）模擬大量並發 user、master 負責 spawn rate、aggregation 跟 Web UI。&lt;/p>
&lt;p>這個定位讓 Locust 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程&lt;/a>。它能把特殊 client 與下游 dependency 放進同一個 user behavior、但也要求團隊處理 runner、資料與可重現性。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a>（JS / Go runtime）比、Locust 用 Python 換到 &lt;em>自訂能力與生態相容&lt;/em>、但代價是單 worker capacity 低、CPU bound 容易先打到自己。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a>（GUI / XML）比、Locust 偏 &lt;em>code-first 工程團隊&lt;/em>、scenario 直接走 Git review、不靠 GUI plugin 拼裝。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling&lt;/a>（Scala DSL）比、Locust 換到 &lt;em>Python team 友善 + 既有 domain library 重用&lt;/em>、但失去 JVM injection profile 的精細度與報表內建。&lt;/p>
&lt;p>關鍵張力：&lt;em>Python 表達力&lt;/em> ↔ &lt;em>runner 效能上限&lt;/em>。Python team 想 reuse domain library、staging fixture、API client 寫壓測腳本時 Locust 是首選；但要心裡有數 &lt;em>單 worker RPS 上限不高&lt;/em>、超過幾千 RPS 就要靠 worker scale-out、不是調 Locust 本身。&lt;/p>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>Python 團隊適合用 Locust 長期維護壓測。既有 domain library、API client、fixture、資料產生器與驗證 helper 都可以被壓測腳本重用。&lt;/p>
&lt;p>自訂 protocol 適合用 Locust。HTTP 之外、如果服務需要 gRPC、WebSocket、binary protocol、message broker client 或自家 SDK、Locust 可以直接接 Python library。&lt;/p>
&lt;p>Distributed load 適合用 Locust worker 擴展。當單機 Python runner 遇到 CPU 或 connection bottleneck、可以用 master / worker 拆開負載產生能力。&lt;/p></description><content:encoded><![CDATA[<p>Locust 的核心責任是用 Python 表達高度自訂的使用者行為與 protocol client。它適合 Python 團隊、需要自訂 client、需要 distributed worker、或 scenario 邏輯比工具內建 sampler 更複雜的壓測流程。</p>
<h2 id="服務定位">服務定位</h2>
<p>Locust 適合把壓測寫成一般 Python 程式。當 workload model 需要呼叫 internal SDK、特殊 protocol、複雜資料準備、狀態機、隨機行為或自訂 client、Locust 可以直接使用 Python 生態來表達。底層架構是 <em>master + worker</em> 分散式 swarm、worker 之間用 Gevent green-thread（非 OS thread）模擬大量並發 user、master 負責 spawn rate、aggregation 跟 Web UI。</p>
<p>這個定位讓 Locust 接到 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 與 <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>。它能把特殊 client 與下游 dependency 放進同一個 user behavior、但也要求團隊處理 runner、資料與可重現性。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>（JS / Go runtime）比、Locust 用 Python 換到 <em>自訂能力與生態相容</em>、但代價是單 worker capacity 低、CPU bound 容易先打到自己。跟 <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>（GUI / XML）比、Locust 偏 <em>code-first 工程團隊</em>、scenario 直接走 Git review、不靠 GUI plugin 拼裝。跟 <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>（Scala DSL）比、Locust 換到 <em>Python team 友善 + 既有 domain library 重用</em>、但失去 JVM injection profile 的精細度與報表內建。</p>
<p>關鍵張力：<em>Python 表達力</em> ↔ <em>runner 效能上限</em>。Python team 想 reuse domain library、staging fixture、API client 寫壓測腳本時 Locust 是首選；但要心裡有數 <em>單 worker RPS 上限不高</em>、超過幾千 RPS 就要靠 worker scale-out、不是調 Locust 本身。</p>
<h2 id="適用場景">適用場景</h2>
<p>Python 團隊適合用 Locust 長期維護壓測。既有 domain library、API client、fixture、資料產生器與驗證 helper 都可以被壓測腳本重用。</p>
<p>自訂 protocol 適合用 Locust。HTTP 之外、如果服務需要 gRPC、WebSocket、binary protocol、message broker client 或自家 SDK、Locust 可以直接接 Python library。</p>
<p>Distributed load 適合用 Locust worker 擴展。當單機 Python runner 遇到 CPU 或 connection bottleneck、可以用 master / worker 拆開負載產生能力。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>Locust 在壓測 stack 中承擔哪一段（user behavior modeling / load generation / distributed swarm）、哪些要外接（<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Prometheus / Grafana</a> 觀測 worker 自身、APM 看目標 saturation）</li>
<li>User class / task weight / on_start lifecycle 的 ownership 設計（誰寫 locustfile、誰 review、誰調 spawn rate）</li>
<li>Distributed master-worker 部署的容量規劃（單 worker user 上限、worker 數量計算、target RPS 對應 worker count）</li>
<li>何時用 Locust、何時走 k6 / JMeter / Gatling 的取捨</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Locust 壓測是否健康、最少看四件事：</p>
<ul>
<li><strong>User class 設計</strong>：每個 <code>HttpUser</code> / <code>User</code> subclass 是不是一個明確的 <em>persona</em>（mobile user / API client / admin user）、<code>wait_time</code> 是否反映真實使用者間隔（不是 0 拼最大 RPS、是 <code>between(1, 5)</code> 模擬 think time）、user state 是否在 instance 內封閉</li>
<li><strong>Task 比例</strong>：<code>@task(weight)</code> 數字是否對應 production traffic mix（80% read / 15% write / 5% admin、不是每個 endpoint 等比例）、weight 是否走版控 review</li>
<li><strong>on_start lifecycle</strong>：login / token fetch / session bootstrap 是否寫在 <code>on_start</code>（每個 user 一次）、不是寫在 <code>@task</code> 裡（每個 request 都重做）— 寫錯位置會讓 auth endpoint 變成主要 traffic</li>
<li><strong>Distributed master-worker</strong>：worker 數量是否夠（單 worker 跑幾千 user 後 CPU 會先打死、不是目標服務先死）、master 是否獨立機器（master 也跑 user 時 aggregation 跟 Web UI 會卡）、<code>--expect-workers</code> 是否設、worker sync drift 是否觀察</li>
</ul>
<p>四件事任一缺失、就是壓測證據可信度的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>locustfile 結構</strong>：locustfile.py 是 Python module、定義 <code>User</code> / <code>HttpUser</code> subclass、每個 user 有 <code>wait_time</code>、若干 <code>@task(weight)</code> method、<code>on_start</code> / <code>on_stop</code> lifecycle hook。執行用 <code>locust -f locustfile.py --host=https://target</code> 起 Web UI、或 <code>locust --headless -u 1000 -r 100 -t 10m</code> 在 CI 跑無 UI 模式。locustfile 應該走 Git review、不是 GUI 改完就跑。</p>
<p><strong>Task weight / wait_time 設計</strong>：weight 是 <em>相對權重</em>、不是百分比 —<code>@task(8)</code> + <code>@task(2)</code> 等於 80% / 20%。<code>wait_time = between(1, 5)</code> 在每個 task 之間等 1-5 秒、模擬 think time；若要拚最大 RPS 用 <code>constant(0)</code>、但同時要意識到這就不是 user behavior 模型、是 <em>throughput probe</em>。</p>
<p><strong>on_start vs @task 的邊界</strong>：<code>on_start(self)</code> 每個 user instance 啟動時跑一次、適合做 login、token fetch、cache warm、fixture lookup；<code>@task</code> 是 user 行為主迴圈、每次選一個 task 跑。把 login 寫在 <code>@task</code> 是常見錯誤、會讓 IdP 變成主壓力來源、不是目標 API。</p>
<p><strong>Gevent-based concurrency</strong>：Locust 用 <a href="https://www.gevent.org/">gevent</a> 的 green-thread 模擬大量 concurrent user、不是 OS thread。意義是單 worker 可以跑幾千個 <em>user</em>、但 CPU bound 工作（JSON serialization、加密、本地計算）會 <em>blocking</em> 整個 worker 的 event loop。<code>gevent.monkey.patch_all()</code> 要在 import 第一行、否則 socket / time / ssl 不會被 patch、blocking call 會卡死 swarm。</p>
<p><strong>Distributed master-worker</strong>：單機到極限時開 distributed — <code>locust --master</code> 起 master、<code>locust --worker --master-host=master.example.com</code> 起 worker。Master 負責 Web UI、spawn rate 控制、result aggregation、stat 收集；worker 負責跑 user。Master 不該跑 user（會跟 aggregation 搶 CPU、stat 失真）。worker 數量計算：先單 worker 拉到 CPU 80% 看能撐多少 user、目標 user 數除這個值 + 20% buffer。</p>
<p><strong>Custom load shape</strong>：除了固定 <code>-u 1000</code>、Locust 支援 <code>LoadTestShape</code> subclass 寫 <em>時間軸負載曲線</em> — spike test（瞬間 0 → 5000 user）、ramp test（線性爬升）、wave test（週期性高低交替）、step test（階梯式增加）。<code>tick()</code> method 每秒回傳 <code>(user_count, spawn_rate)</code>。用 custom shape 才能模擬 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 那種 ticket drop 瞬間衝擊。</p>
<p><strong>Prometheus exporter / 觀測</strong>：Locust 內建 stat 只是 in-memory 的 p50 / p95 / p99 / RPS、結束就消失。長期觀測接 <a href="https://github.com/ContainerSolutions/locust_exporter">locust-prometheus-exporter</a>（或 <code>--csv result.csv</code> 自己抓）、把 metric 推到 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Prometheus</a> + Grafana。<strong>worker 自身的 CPU / memory / network</strong> 一定要同時觀測、不然分不出是目標 saturation 還是 worker 已死。</p>
<p><strong>Locust Cloud（managed SaaS）</strong>：2024 後 Locust 推官方 <a href="https://docs.locust.cloud/">Locust Cloud</a>、託管 master + worker + result storage、付費換 ops 成本。自管 master-worker 對 CI / staging 是合理的；production 等級的 scale test（10k+ concurrent user）跑一次要拉幾十台 worker、用 Cloud 省 infra ops 是合理 trade-off。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Locust</th>
          <th>k6</th>
          <th>JMeter</th>
          <th>Gatling</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>腳本語言</td>
          <td>Python（generic）</td>
          <td>JavaScript (k6 runtime)</td>
          <td>XML / GUI / Groovy</td>
          <td>Scala DSL（也支援 Java / Kotlin）</td>
      </tr>
      <tr>
          <td>Runtime</td>
          <td>Python + Gevent green-thread</td>
          <td>Go-based、單 binary、低 overhead</td>
          <td>JVM、heavy</td>
          <td>JVM、async actor model</td>
      </tr>
      <tr>
          <td>單 worker capacity</td>
          <td>中低（Python overhead、千級 user）</td>
          <td>高（Go runtime、萬級 VU 單機）</td>
          <td>中（JVM tuning 後可用）</td>
          <td>高（Akka actor、效能好）</td>
      </tr>
      <tr>
          <td>Distributed mode</td>
          <td>內建 master-worker</td>
          <td>內建 k6 Cloud / k6 Operator</td>
          <td>內建 master-slave</td>
          <td>Gatling Enterprise（前 FrontLine）</td>
      </tr>
      <tr>
          <td>User behavior 彈性</td>
          <td>高 — 一般 Python、任意 library</td>
          <td>中 — JS 但 k6 runtime 受限</td>
          <td>中 — GUI 拼裝 + plugin</td>
          <td>中高 — Scala DSL 表達 simulation</td>
      </tr>
      <tr>
          <td>Custom protocol</td>
          <td>強 — 接任何 Python library</td>
          <td>強 — 有 gRPC / WS / Kafka extension</td>
          <td>強但繁瑣 — plugin 生態廣</td>
          <td>中 — 主要 HTTP / WS</td>
      </tr>
      <tr>
          <td>CI / headless</td>
          <td><code>--headless</code> 支援</td>
          <td>CI-first design</td>
          <td>non-GUI mode 支援</td>
          <td>內建支援</td>
      </tr>
      <tr>
          <td>Report / UI</td>
          <td>Web UI 即時 + CSV 匯出</td>
          <td>k6 Cloud / Grafana / 簡 stdout</td>
          <td>GUI listener / HTML report</td>
          <td>HTML report 內建、視覺豐富</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>緩（Python team）/ 陡（非 Python）</td>
          <td>中 — JS-style scripting</td>
          <td>緩（GUI）/ 陡（深度 tuning）</td>
          <td>陡 — Scala 語法</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Python team + 自訂 behavior / client</td>
          <td>DevOps + CI / 標準 HTTP / 高 RPS 單機</td>
          <td>非工程角色協作 / legacy enterprise</td>
          <td>JVM team + 精細 injection profile</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>低 — Python 腳本可移植</td>
          <td>中 — k6 runtime 綁定</td>
          <td>中 — XML jmx 不易他移</td>
          <td>中 — Scala DSL 綁定</td>
      </tr>
  </tbody>
</table>
<p>選 Locust 的核心訴求：<em>Python team + custom user behavior + 既有 domain library 重用</em>、且能投入 worker scale-out 預算（單 worker capacity 低、要靠分散式補）+ scenario 走 Git review 不靠 GUI。標準 HTTP 高 RPS 單機壓測直接走 k6 更快、非工程角色協作壓測走 JMeter、JVM team 精細模擬走 Gatling。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Distributed Locust 的 master-worker swarm</strong>：production scale test 通常需要 10-100 個 worker。實作要點：worker 之間 <em>不要</em> 共享 state、shared resource 由 master 統一發（用 <a href="https://zeromq.org/">zeromq</a> message bus）；worker 加入 / 離開時 user 會 redistribute、避免 user index 當 unique key；worker 跨 region 跑時 <em>latency 來自 worker → target 不只是 target 內部</em>、要在 worker 本身的 region 對齊。</p>
<p><strong>Custom load shape（spike / wave / step）</strong>：<code>LoadTestShape.tick(self)</code> return <code>(user_count, spawn_rate)</code> tuple 每秒被叫一次。Spike test：前 60 秒 0 user、第 61 秒瞬間衝 5000、模擬 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 admission storm。Wave test：sine wave 在 1000-3000 user 之間振盪、測 autoscaling 反應速度。Step test：每 5 分鐘加 1000 user、觀察哪一階開始降級。custom shape 是 Locust 比 k6 強的點之一。</p>
<p><strong>跟 Prometheus exporter 整合</strong>：locust-prometheus-exporter 把 Locust stat 推到 Prometheus / Grafana、做長期 baseline、跨 test 比較、p99 退化偵測。實務上要在 dashboard 同時放 <em>Locust 內部 stat</em> + <em>worker host metric</em> + <em>目標服務 APM</em>、三層 stack 起來才能判讀是 runner 還是目標 saturation。</p>
<p><strong>Locust Cloud（managed SaaS）</strong>：2024+ 官方 SaaS、託管 master + worker + result + dashboard。trade-off：自管適合 CI / staging / 內網壓測（target 跑在內網時 Cloud 連不到）；Cloud 適合大規模一次性 scale test（拉 50 worker 跑 2 小時、跑完即停、不想自己 infra ops）。</p>
<h2 id="操作成本">操作成本</h2>
<p>Locust 的主要成本是 runner overhead 與分散式治理。Python runner 的效能上限要用 worker scale-out 解決；壓測結論要同時檢查目標服務 saturation 與 worker 本身 CPU、connection、network 是否已成瓶頸。</p>
<p>腳本工程成本來自自由度。Python 可以很快寫出複雜行為、也容易把測試資料、randomness、side effect、sleep 與 exception handling 寫散；團隊要維持 scenario structure、fixture、logging 與 artifact 標準。</p>
<p>自訂 client 成本來自校正。使用 SDK 或 custom protocol client 時、要確認 client retry、timeout、connection pool 與 serialization 行為是否接近 production、避免 runner 模擬出不存在的壓力形狀。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Worker CPU 100% 但目標服務閒</strong>：Python runner 先死、不是 target saturation — 加 worker 數量、或檢查 task 裡有沒有 CPU bound 的本地計算（大 JSON parse、加密、本地 fixture 生成）擠掉 event loop</li>
<li><strong>Gevent monkey-patch gotcha</strong>：<code>requests</code> / <code>psycopg2</code> / 自家 SDK 在第三方 library 內部 blocking call、整個 worker 卡住 — <code>gevent.monkey.patch_all()</code> 一定要寫在 import 第一行；無法 patch 的 C extension（如 native MySQL driver）改用 gevent-friendly client</li>
<li><strong>RPS 達不到目標 / 看起來像 target 慢</strong>：實際是 worker connection pool 耗盡、或 worker 本身網卡飽和 — 觀測 worker 本身的 TCP socket 數、netstat ESTABLISHED、network throughput；不要直接 blame target</li>
<li><strong>Distributed sync drift</strong>：worker 之間 user count 不平均、aggregation 顯示 RPS 抖動 — <code>--expect-workers=N</code> 確認 master 等所有 worker join 才開測；worker 跨 region 時 message bus latency 也會影響 sync</li>
<li><strong>on_start 在 @task 裡跑</strong>：壓測啟動瞬間打爆 auth endpoint、看到 IdP latency 飆高以為是 target — 把 login / token fetch 移到 <code>on_start</code>、每個 user 只做一次</li>
<li><strong>wait_time = 0 拼最大 RPS 結果結論奇怪</strong>：這已經不是 user behavior 是 throughput probe、p99 跟 production 對不上 — 改成 <code>between(1, 5)</code> 模擬 think time 或寫 custom shape</li>
<li><strong>Web UI 卡 / master CPU 100%</strong>：master 同時在跑 user + aggregation — <code>locust --master</code> 跟 worker 拆機器、master 不跑 user</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>標準 HTTP / 高 RPS 單機 / CI-first</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a></td>
      </tr>
      <tr>
          <td>非工程角色協作 / GUI 拼裝</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a></td>
      </tr>
      <tr>
          <td>JVM team / 精細 injection profile</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a></td>
      </tr>
      <tr>
          <td>極簡 HTTP probe / 命令列 one-shot</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a></td>
      </tr>
      <tr>
          <td>Production traffic replay / shadow</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a> / <a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a></td>
      </tr>
      <tr>
          <td>壓測結果回寫到效能工程 lifecycle</td>
          <td><a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>、<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>locustfile 完整語法 reference、<code>User</code> 跟 <code>HttpUser</code> 的 attribute 細節</li>
<li>Locust Cloud 計費跟 quota 細節（看官方 docs）</li>
<li>gevent 跟 asyncio 的取捨（Locust 選了 gevent、不在本頁討論替代）</li>
<li>壓測證據怎麼歸檔（看 <a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">9.7 evidence package</a> 通則）</li>
</ul>
<h2 id="evidence-package">Evidence Package</h2>
<p>Locust 結果應回寫到 evidence package。最小欄位包括 locustfile version、user class、task weight、spawn rate、worker count、client library version、target environment、p95 / p99、error rate、throughput、target saturation metric、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Locust 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>locustfile、CSV / JSON result、dashboard link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / logs 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>user behavior coverage、fixture freshness</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>worker capacity、client realism</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>worker bottleneck、custom client 偏差、資料偏差</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是區分目標瓶頸與 runner 瓶頸。Locust 分散式測試要同時保存 worker 數量、worker 資源、spawn rate 與 client behavior、讓 reviewer 知道壓力是否真的打到目標服務。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>Locust 適合回寫需要高度自訂 user behavior 的案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 雙峰 workload</a> 的投注行為模型、<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 admission / token flow、<a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay mobile payment messaging</a> 的外部推送與下游 quota 模擬、<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Niantic Pokémon GO 50x surge</a> 的玩家移動 + 互動混合行為、以及 <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom COVID 30x surge</a> 的會議建立 / 加入 / 離開行為混合。</p>
<p>這些案例的重點是 domain behavior。Locust 頁引用案例時、要把 case 轉成 user class、task weight、custom client、downstream mock 與 worker capacity、再把總 RPS 放回這些行為條件下判讀 — 例如 Pokémon GO 玩家行為跟一般 web user 完全不同（持續 GPS 上報 + 偶發互動）、不能直接用 HTTP RPS 衡量；SeatGeek waiting room 要寫 <code>LoadTestShape</code> 模擬 ticket drop 瞬間衝擊、不是穩態 RPS。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>、<a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>、<a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>、<a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a></li>
<li>跨類：<a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a>（production traffic replay 替代 synthetic load）</li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">4 Observability</a>（worker 自身 + 目標 APM 雙觀測）</li>
<li>官方：<a href="https://docs.locust.io/">Locust documentation</a></li>
</ul>
]]></content:encoded></item></channel></rss>