
本文介绍在 k6 多虚拟用户(vu)并发场景下,如何避免多个 vu 重复操作同一资源(如重复删除已删 id),通过基于 vu 编号的分片策略实现 id 的均匀、无冲突分配。
本文介绍在 k6 多虚拟用户(vu)并发场景下,如何避免多个 vu 重复操作同一资源(如重复删除已删 id),通过基于 vu 编号的分片策略实现 id 的均匀、无冲突分配。
在使用 k6 对 CRUD 流程(登录 → 列表获取 ID → 编辑 → 删除)进行端到端压力测试时,单 VU 场景天然串行、无竞争,但一旦扩展至多个 VU(如 --vus 3),多个线程会并发调用同一列表接口并各自遍历全部 ID,导致后续编辑/删除操作发生资源争用——典型表现为「404 Not Found」或「ID already deleted」错误。这类错误并非系统能力瓶颈,而是测试逻辑缺陷,会干扰真实性能指标分析。
根本解决思路是:让每个 VU 只处理其专属子集的 ID,而非全部 ID。最轻量、高效且无需共享状态的方式是利用 k6 内置变量 __VU(当前 VU 序号,从 1 开始)与全局 ID 列表做模运算分片:
import { check, sleep } from 'k6';
import http from 'k6/http';
export const options = {
vus: 3,
iterations: 1,
};
export default function () {
// Step 1: Login (omitted for brevity)
// const resLogin = http.post('https://api.example.com/login', ...);
// Step 2: Fetch list of IDs (e.g., GET /api/items)
const listRes = http.get('https://api.example.com/items');
const items = listRes.json().data || [];
const ids = items.map(item => item.id);
// ✅ Key: Assign each VU a disjoint subset using modulo sharding
const myIds = ids.filter((_, idx) => idx % __ENV.VUS === __VU - 1);
// Optional: Log assignment for debugging
console.log(`VU ${__VU} assigned ${myIds.length} IDs: [${myIds.slice(0, 3).join(', ')}...]`);
// Step 3: Edit each assigned ID
myIds.forEach(id => {
http.put(`https://api.example.com/items/${id}`, JSON.stringify({ status: 'edited' }));
sleep(0.1);
});
// Step 4: Delete each assigned ID
myIds.forEach(id => {
const delRes = http.del(`https://api.example.com/items/${id}`);
check(delRes, { 'delete success': (r) => r.status === 200 || r.status === 204 });
sleep(0.1);
});
}? 原理说明:
idx % __ENV.VUS === __VU - 1确保第i个 ID(索引从 0 起)仅被第(i % VUS) + 1号 VU 处理。例如 9 个 ID、3 个 VU 时:
- VU 1 处理索引 0, 3, 6 → ID[0], ID[3], ID[6]
- VU 2 处理索引 1, 4, 7 → ID[1], ID[4], ID[7]
- VU 3 处理索引 2, 5, 8 → ID[2], ID[5], ID[8]
完全无重叠,且负载均衡。
⚠️ 注意事项:
- 此方案要求列表 API 返回的 ID 顺序稳定(如按
id ASC排序),否则不同 VU 可能因响应顺序差异误判归属; - 若 ID 总数 myIds.length === 0),属正常现象,可在日志中提示;
- 避免在
setup()中预分配 ID 并存入全局数组——k6 的 VU 是隔离的,无法跨 VU 共享可变状态,setup()返回值仅在 init context 可用,不适用于运行时协调; - 如需更复杂调度(如动态负载均衡、ID 池复用),应引入外部协调服务(如 Redis)或改用 k6/execution-segment 分段执行,但会显著增加架构复杂度。
综上,基于索引模分片是 k6 多 VU 场景下实现无锁、无状态、高可靠资源分配的推荐实践,兼顾简洁性、可维护性与压测真实性。

















