當單機硬體資源成為效能測試的瓶頸時,Locust 的 分散式測試 (Distributed Mode) 功能就顯得至關重要。它讓我們可以結合多台機器的力量,模擬大規模的用戶負載。
分散式測試是將負載產生任務分散到多台機器(Worker)上,由一台主機(Main)統一協調和管理。
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("/")
這個腳本無論在單機或分散式模式下都可以直接運行。
你需要分別啟動 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 數量。
假設你有:
192.168.1.100
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
確保以下埠號可以通訊:
# 在 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 機器上檢查:
http://192.168.1.100:8089
curl http://192.168.1.100:8089/stats/workers
常見問題解決:
# 在 Worker 機器上測試網路連通性
telnet 192.168.1.100 5557
# 或
nc -zv 192.168.1.100 5557
# 在兩台機器上都執行
locust --version
# 比較兩台機器上的檔案
md5sum your_locust_file.py
對於複雜的測試環境,使用 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
機器 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 分散式測試的核心概念:
透過分散式測試,你可以更準確地模擬高併發場景,為你的系統穩定性提供更可靠的效能數據。