跳至主要內容
版本:4.x

負載測試

由於 Socket.IO 有其自己的通訊協定,包括握手、心跳和自訂封包編碼,因此負載測試 Socket.IO 伺服器的最簡單方法就是使用 Socket.IO 用戶端程式庫並建立大量的用戶端。

有兩種經典的解決方案可以做到這一點

Artillery

Artillery 是用於負載測試應用程式的絕佳工具。它允許建立連線、傳送事件和檢查確認。

文件可以在這裡找到。

重要事項:預設安裝附帶 v2 用戶端,這與 v3/v4 伺服器不相容。您需要為此安裝自訂引擎:https://github.com/ptejada/artillery-engine-socketio-v3

安裝

$ npm install artillery artillery-engine-socketio-v3

範例情境

# my-scenario.yml
config:
target: "http://localhost:3000"
phases:
- duration: 60
arrivalRate: 10
engines:
socketio-v3: {}

scenarios:
- name: My sample scenario
engine: socketio-v3
flow:
# wait for the WebSocket upgrade (optional)
- think: 1

# basic emit
- emit:
channel: "hello"
data: "world"

# emit an object
- emit:
channel: "hello"
data:
id: 42
status: "in progress"
tags:
- "tag1"
- "tag2"

# emit in a custom namespace
- namespace: "/my-namespace"
emit:
channel: "hello"
data: "world"

# emit with acknowledgement
- emit:
channel: "ping"
acknowledge:
match:
value: "pong"

# do nothing for 30 seconds then disconnect
- think: 30

執行此情境

$ npx artillery run my-scenario.yml

Artillery 也隨附許多很棒的功能,例如 將指標發布到各種端點從 AWS 執行測試 的能力。

它唯一的限制是您無法輕易測試伺服器到用戶端的事件,因為 Artillery DSL 更適合傳統的用戶端到伺服器通訊。這讓我們進入 下一部分

手動建立用戶端

以下是建立一千個 Socket.IO 用戶端並監控每秒接收封包數量的基本腳本

const { io } = require("socket.io-client");

const URL = process.env.URL || "http://localhost:3000";
const MAX_CLIENTS = 1000;
const POLLING_PERCENTAGE = 0.05;
const CLIENT_CREATION_INTERVAL_IN_MS = 10;
const EMIT_INTERVAL_IN_MS = 1000;

let clientCount = 0;
let lastReport = new Date().getTime();
let packetsSinceLastReport = 0;

const createClient = () => {
// for demonstration purposes, some clients stay stuck in HTTP long-polling
const transports =
Math.random() < POLLING_PERCENTAGE ? ["polling"] : ["polling", "websocket"];

const socket = io(URL, {
transports,
});

setInterval(() => {
socket.emit("client to server event");
}, EMIT_INTERVAL_IN_MS);

socket.on("server to client event", () => {
packetsSinceLastReport++;
});

socket.on("disconnect", (reason) => {
console.log(`disconnect due to ${reason}`);
});

if (++clientCount < MAX_CLIENTS) {
setTimeout(createClient, CLIENT_CREATION_INTERVAL_IN_MS);
}
};

createClient();

const printReport = () => {
const now = new Date().getTime();
const durationSinceLastReport = (now - lastReport) / 1000;
const packetsPerSeconds = (
packetsSinceLastReport / durationSinceLastReport
).toFixed(2);

console.log(
`client count: ${clientCount} ; average packets received per second: ${packetsPerSeconds}`
);

packetsSinceLastReport = 0;
lastReport = now;
};

setInterval(printReport, 5000);

您可以將它用作載入測試您自己的應用程式的起點。