iT邦幫忙

2025 iThome 鐵人賽

DAY 10
1

當單機硬體資源成為效能測試的瓶頸時,Locust 的 分散式測試 (Distributed Mode) 功能就顯得至關重要。它讓我們可以結合多台機器的力量,模擬大規模的用戶負載。

什麼是分散式測試?

分散式測試是將負載產生任務分散到多台機器(Worker)上,由一台主機(Main)統一協調和管理。

  • Main 節點:不產生實際請求,主要負責管理 Worker、彙總測試數據,並提供 Web UI 介面供使用者監控。
  • Worker 節點:接收 Main 的指令,實際執行測試任務(運行 User Task),並將統計數據回報給 Main。

為什麼需要分散式測試?

  1. 突破單機限制:任何單一機器都有其 CPU、記憶體和網路連線數的上限,通常難以模擬數千個以上的併發使用者。分散式測試可以輕鬆突破此限制。
  2. 進行大規模負載測試:透過增加 Worker 節點,可以線性地擴展測試規模,模擬數萬甚至數十萬的併發使用者。
  3. 模擬地理分佈:若將 Worker 部署在全球不同的數據中心,可以模擬來自不同地理位置的用戶,測試系統的全球服務能力和 CDN 效能。

分散式架構

Locust 的分散式架構非常簡單,Main 和 Worker 之間透過 ZeroMQ 協定進行高效通訊。

                      +-----------------+
                      |   Main Node     |
                      | - Web UI        |
                      | - 數據統計      |
                      +-----------------+
                             |
           +-----------------+-----------------+
           |                 |                 |
+-----------------+ +-----------------+ +-----------------+
|   Worker Node 1 | |   Worker Node 2 | |   Worker Node N |
| - 執行測試任務  | | - 執行測試任務  | | - 執行測試任務  |
| - 回報統計數據  | | - 回報統計數據  | | - 回報統計數據  |
+-----------------+ +-----------------+ +-----------------+

實作範例

分散式測試的測試腳本與單機模式幾乎完全相同。Locust 會自動處理 Main 和 Worker 的分工。

from locust import HttpUser, task, between
import os

class DistributedTestUser(HttpUser):
    wait_time = between(1, 3)
    host = "http://127.0.0.1:8089" # 替換成你的目標服務 host

    def on_start(self):
        """
        在 User 啟動時執行,可以用來識別 Worker。
        """
        # 透過環境變數可以得知自己是否在 Worker 上運行
        if os.environ.get('LOCUST_RUNNER') == 'worker':
            worker_id = os.environ.get('HOSTNAME', 'unknown-worker') # Docker/K8s 中常用 HOSTNAME
            print(f"Worker {worker_id} a user has spawned!")

    @task
    def simple_request(self):
        """
        一個簡單的 API 請求任務。
        """
        self.client.get("/stats/requests")

    @task
    def another_request(self):
        """
        另一個 API 請求任務。
        """
        self.client.get("/")

這個腳本無論在單機或分散式模式下都可以直接運行。

如何執行分散式測試

1. 使用終端機 (CLI)

你需要分別啟動 Main 和 Worker 程序。

步驟 1: 啟動 Main 節點
在主機上執行以下命令,--master 參數表示這是一個 Main 節點。

locust -f your_locust_file.py --master

步驟 2: 啟動 Worker 節點
在所有 Worker 機器上執行以下命令,--worker 表示這是一個 Worker,並透過 --master-host 指向 Main 的 IP 位址。

# 假設 Main 的 IP 是 192.168.0.100
locust -f your_locust_file.py --worker --master-host=192.168.0.100

啟動所有 Worker 後,打開 Main 的 Web UI (預設為 http://localhost:8089),你將會看到已連線的 Worker 數量。

跨機器部署實戰範例

場景:兩台機器分別部署 Main 和 Worker

假設你有:

  • 機器 A (Main):IP 是 192.168.1.100
  • 機器 B (Worker):IP 是 192.168.1.101

在機器 A 上(Main 節點):

# 1. 確保測試腳本存在
ls your_locust_file.py

# 2. 啟動 Main 節點,綁定到所有網路介面
locust -f your_locust_file.py --master --master-bind-host=0.0.0.0

# 或者指定特定網路介面
locust -f your_locust_file.py --master --master-bind-host=192.168.1.100

在機器 B 上(Worker 節點):

# 1. 確保相同的測試腳本存在
ls your_locust_file.py

# 2. 連線到 Main 節點
locust -f your_locust_file.py --worker --master-host=192.168.1.100

網路防火牆設置

確保以下埠號可以通訊:

  • 5557:Main-Worker 通訊埠
  • 8089:Web UI 埠(僅 Main 需要)
# 在 Main 機器上檢查埠號是否開啟
netstat -tlnp | grep 5557
netstat -tlnp | grep 8089

# Ubuntu/Debian 防火牆設置
sudo ufw allow 5557
sudo ufw allow 8089

# CentOS/RHEL 防火牆設置  
sudo firewall-cmd --permanent --add-port=5557/tcp
sudo firewall-cmd --permanent --add-port=8089/tcp
sudo firewall-cmd --reload

驗證連線狀態

在 Main 機器上檢查:

  1. 打開瀏覽器造訪 http://192.168.1.100:8089
  2. 在 Web UI 右上角可看到 Worker 連線數量
  3. 或使用命令列檢查:
curl http://192.168.1.100:8089/stats/workers

故障排除

常見問題解決:

  1. Worker 無法連線到 Main
# 在 Worker 機器上測試網路連通性
telnet 192.168.1.100 5557
# 或
nc -zv 192.168.1.100 5557
  1. 檢查 Locust 版本一致性
# 在兩台機器上都執行
locust --version
  1. 檢查測試腳本是否相同
# 比較兩台機器上的檔案
md5sum your_locust_file.py

2. 使用 Docker 跨機器部署

單機 Docker Compose 部署

對於複雜的測試環境,使用 Docker Compose 可以更輕鬆地管理分散式測試。

docker-compose.yml 設定檔範例:

version: '3.8'

services:
  main:
    image: locustio/locust
    ports:
      - "8089:8089" # Web UI
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/your_locust_file.py --master --web-host 0.0.0.0

  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/your_locust_file.py --worker --master-host main
    depends_on:
      - main

執行命令:

# 啟動 1 個 Main 和 1 個 Worker
docker-compose up -d

# 如果需要擴展 Worker 數量,例如擴展到 4 個
docker-compose up -d --scale worker=4

# 停止所有服務
docker-compose down

跨機器 Docker 部署

機器 A(Main 節點)- docker-compose-main.yml

version: '3.8'

services:
  main:
    image: locustio/locust
    ports:
      - "8089:8089"  # Web UI
      - "5557:5557"  # Main-Worker 通訊
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/your_locust_file.py --master --master-bind-host=0.0.0.0
    networks:
      - locust-network

networks:
  locust-network:
    driver: bridge

機器 B(Worker 節點)- docker-compose-worker.yml

version: '3.8'

services:
  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/your_locust_file.py --worker --master-host=192.168.1.100
    deploy:
      replicas: 2  # 可以在同一台機器上啟動多個 Worker

執行步驟:

# 在機器 A 上啟動 Main
docker-compose -f docker-compose-main.yml up -d

# 在機器 B 上啟動 Worker
docker-compose -f docker-compose-worker.yml up -d

# 擴展 Worker 數量(在機器 B 上)
docker-compose -f docker-compose-worker.yml up -d --scale worker=4

總結

今天我們學習了 Locust 分散式測試的核心概念:

  1. Main-Worker 架構:了解了 Main 負責協調、Worker 負責執行的分工模式。
  2. 執行方式:掌握了如何透過 CLI 和 Docker Compose 啟動分散式測試。
  3. 應用場景:理解了何時需要使用分散式測試來突破單機限制,實現大規模負載。

透過分散式測試,你可以更準確地模擬高併發場景,為你的系統穩定性提供更可靠的效能數據。


上一篇
Day 09 - Locust 負載模型:Linear vs Step Load Mode 詳細分析
下一篇
Day11 - Locust 配置文件管理 (Configuration Files)
系列文
Vibe Coding 後的挑戰:Locust x Loki 負載及監控13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言