K6测试中如何存储Processing IDs?寻求非多文件存储方案
在k6中持久化Processing ID的可行方案
k6的虚拟用户(VU)运行在完全隔离的环境中,没有内置的共享可变内存机制,测试结束后所有内存数据都会被清除,所以无法通过内存共享来持久化需要跨测试使用的Processing ID。针对你的需求,以下是几种无需创建数千个单独文件的解决方案:
方案一:批量写入单个文件(本地文件系统)
通过k6的k6/x/fs扩展模块,将所有Processing ID写入同一个文件(按行存储),避免单个ID对应单个文件的繁琐。为了避免多VU并发写入的冲突,可以先让每个VU写入临时文件,测试结束后通过teardown函数合并成主文件。
收集ID的脚本示例
import http from 'k6/http'; import { sleep } from 'k6'; import fs from 'k6/x/fs'; import { __VU } from 'k6/execution'; export default function () { // 发起API请求获取Processing ID const apiRes = http.post( 'https://your-api-domain.com/start-processing', JSON.stringify({ /* 你的请求体参数 */ }), { headers: { 'Content-Type': 'application/json' } } ); const processingId = apiRes.json().processingId; // 假设接口返回的JSON包含该字段 // 写入当前VU专属的临时文件 const tempFilePath = `processing_ids_vu-${__VU}.txt`; fs.appendFile(tempFilePath, `${processingId}\n`, 'utf8'); sleep(1); } export function teardown() { const mainFilePath = 'processing_ids.txt'; // 清空主文件(若已存在) if (fs.exists(mainFilePath)) { fs.unlink(mainFilePath); } // 合并所有VU的临时文件到主文件 for (let vuNum = 1; vuNum <= __ENV.K6_VUS; vuNum++) { const tempFilePath = `processing_ids_vu-${vuNum}.txt`; if (fs.exists(tempFilePath)) { const tempContent = fs.readFile(tempFilePath, 'utf8'); fs.appendFile(mainFilePath, tempContent, 'utf8'); // 删除临时文件 fs.unlink(tempFilePath); } } }
后续下载PDF的脚本示例
import http from 'k6/http'; import { sleep } from 'k6'; import fs from 'k6/x/fs'; export default function () { // 读取主文件中的所有Processing ID const fileContent = fs.readFile('processing_ids.txt', 'utf8'); const processingIds = fileContent.trim().split('\n'); // 遍历ID发起下载请求 for (const id of processingIds) { const downloadRes = http.get( `https://your-api-domain.com/download-pdf/${id}`, { responseType: 'binary' } ); // 可选:保存PDF到本地 fs.writeFile(`downloaded_pdf_${id}.pdf`, downloadRes.body, 'binary'); sleep(1); } }
方案二:使用Redis存储(跨测试/分布式场景)
如果需要跨多个测试运行或分布式测试环境共享ID,可以用k6的Redis扩展将ID存入Redis集合,后续测试直接从Redis读取。
收集ID的脚本示例
import http from 'k6/http'; import { sleep } from 'k6'; import redis from 'k6/x/redis'; // 初始化Redis客户端 const redisClient = redis.newClient({ addr: 'redis://your-redis-host:6379', password: '', // 若Redis有密码则填写 db: 0, }); export default function () { const apiRes = http.post( 'https://your-api-domain.com/start-processing', JSON.stringify({ /* 请求体参数 */ }), { headers: { 'Content-Type': 'application/json' } } ); const processingId = apiRes.json().processingId; // 将ID存入Redis集合(自动去重) redisClient.sadd('processing_ids', processingId); sleep(1); } export function teardown() { redisClient.close(); }
后续下载PDF的脚本示例
import http from 'k6/http'; import { sleep } from 'k6'; import redis from 'k6/x/redis'; import fs from 'k6/x/fs'; const redisClient = redis.newClient({ addr: 'redis://your-redis-host:6379', password: '', db: 0, }); export default function () { // 从Redis获取所有Processing ID const processingIds = redisClient.smembers('processing_ids'); for (const id of processingIds) { const downloadRes = http.get( `https://your-api-domain.com/download-pdf/${id}`, { responseType: 'binary' } ); fs.writeFile(`downloaded_pdf_${id}.pdf`, downloadRes.body, 'binary'); sleep(1); } } export function teardown() { redisClient.close(); }
方案三:使用数据库存储(结构化持久化)
如果需要对ID进行更复杂的管理(比如记录生成时间、状态),可以用k6的数据库扩展(如k6/x/sql)将ID存入SQLite、PostgreSQL等数据库。
核心思路
- 在测试初始化阶段创建存储ID的数据表
- 获取Processing ID后插入数据库
- 后续测试从数据库查询所有ID并执行下载操作
内容的提问来源于stack exchange,提问作者tomvda
相关产品推荐
相关产品推荐

