負載測試
由於 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);
您可以將它用作載入測試您自己的應用程式的起點。