k6测试:HTTP请求并发执行,WebSocket请求串行执行问题求助
解决k6中WebSocket请求无法并发执行的问题
我之前也碰到过一模一样的问题,这其实和k6对WebSocket连接的处理逻辑,以及你当前的代码结构有直接关系。先帮你拆解下原因,再给出具体的解决建议:
问题根源
k6的每个VUS(虚拟用户)是独立的执行上下文,你的HTTP登录请求loginReq()能正常并发,是因为每个VUS都在自己的上下文里独立执行了登录逻辑。但WebSocket的searchItem串行执行,大概率是这两个原因:
- 你的
handler.js里的searchItem依赖了全局共享状态(比如全局变量、锁机制),导致VUS之间的操作互相阻塞; - 当前代码里的WebSocket回调逻辑没有让每个VUS独立触发操作,反而隐含了“等待前一个操作完成再执行下一个”的串行逻辑。
具体解决建议
1. 确保每个VUS独立处理WebSocket连接与操作
修改你的默认函数,让每个VUS在建立WebSocket连接后,直接在自己的连接回调里触发搜索操作,不要依赖全局的回调配置。调整后的代码示例:
import http from "k6/http"; import { check } from "k6"; import ws from "k6/ws"; import { loginReq } from "./lib/login.js"; import { respMsg, close, searchItem } from "./lib/handler.js" export default function() { // 每个VUS独立完成HTTP登录 let jsess = loginReq(); let params = { "JSESSION": jsess }; const wsUrl = "你的实际WebSocket地址"; // 每个VUS独立建立WebSocket连接 let response = ws.connect(wsUrl, params, (socket) => { socket.on("open", () => { console.log(`VUS ${__VU} created user searching for item...`); // 连接成功后立即触发当前VUS的搜索操作 searchItem(socket); }); socket.on("message", respMsg); socket.on("close", close); }); check(response, { "WS连接成功": (r) => r && r.status === 101 }); }
2. 修正searchItem的实现逻辑
确保searchItem是针对单个WebSocket连接的独立操作,不要使用全局状态或阻塞逻辑。比如修改handler.js里的searchItem:
export function searchItem(socket) { // 向当前连接发送搜索请求 socket.send(JSON.stringify({ action: "search", query: "目标商品关键词" })); // 可选:监听当前连接的响应,处理搜索结果 socket.once("message", (msg) => { const resp = JSON.parse(msg); if (resp.success) { console.log(`VUS ${__VU} search successful!`); } }); }
3. 排查服务器端的并发限制
如果调整代码后还是串行执行,就要检查你的WebSocket服务端是否有并发连接限制,或者针对单个会话加了锁机制——比如服务器端是否限制了同一时间只能处理一个WebSocket请求,这种情况下需要修改服务端的配置或逻辑。
4. 验证并发效果
重新执行命令:
k6 run --vus 10 --duration 10s
正常情况下,日志应该会同时出现多个VUS的“searching for item...”输出,而不是逐个串行打印。
内容的提问来源于stack exchange,提问作者Art Sam
相关产品推荐
相关产品推荐

