JMeter分布式压测下BeanShell写CSV出现Token截断与空行问题
主从压测场景下BeanShell写Token到CSV的异常修复
异常根因
当前使用的代码在单节点运行时无异常,在3节点主从压测架构下出现空行、Token截断的核心原因有三点:
- 同节点多线程并发写入无同步机制:单节点下高并发线程会同时以追加模式打开同一个
/tmp/token.csv文件,操作系统层面的文件句柄竞争会导致流写入中断,出现内容截断、交叉写入的问题 - 未对Token内容做清洗:部分接口返回的Token值末尾会夹带回车、换行字符,原有代码未做过滤就直接写入,再拼接固定换行符,就会出现多余空行
- 流操作的可靠性不足:原有代码每次写入都重新打开、关闭文件,未做强制刷盘操作,流缓冲区的内容可能因为节点高负载未完整写入磁盘就被释放,导致内容截断
修复后可直接复用的代码
import java.io.File; import java.io.FileWriter; import java.io.BufferedWriter; // 全局同步锁,解决同节点并发写入竞争问题 if (lock == null) { lock = new Object(); } synchronized (lock) { String accesstoken = vars.get("UserTOKEN"); // 空值判断,避免写入空行 if (accesstoken == null || accesstoken.trim().isEmpty()) { return; } // 清洗Token内夹带的换行、回车字符,避免多余空行 accesstoken = accesstoken.replaceAll("[\r\n]", "").trim(); File file = new File("/tmp/token.csv"); // 用try-with-resources自动管理流关闭,避免资源泄漏 try ( FileWriter fileWriter = new FileWriter(file, true); BufferedWriter out = new BufferedWriter(fileWriter); ) { out.write(accesstoken); out.newLine(); out.flush(); // 强制刷盘,确保内容完整落盘 } }
修复逻辑说明
- 新增全局同步锁:同节点并发线程写入时按顺序排队操作文件,从根源上避免句柄竞争导致的内容截断
- 新增Token清洗逻辑:自动剔除Token中夹带的换行、回车字符,结合空值判断,从根源上消除多余空行
- 采用自动资源管理+强制刷盘机制:确保写入的内容完整落盘,不会因为流提前释放导致内容丢失
- 替换硬编码换行符:用BufferedWriter自带的
newLine()方法适配不同Slave节点的系统换行规范,避免跨平台格式混乱
主从压测场景的额外提示
- 主从架构下,每台Slave节点写入的是自身本地磁盘的
/tmp/token.csv,最终需要分别登录3台Slave节点收集文件内容,不要在Master节点读取该路径的文件 - 不要将写入路径配置为跨节点网络挂载路径,否则高并发下的网络IO延迟会进一步加剧写入异常
- 若不需要自定义写入逻辑,可直接使用JMeter原生的保存响应到文件后置处理器完成Token输出,稳定性优于手动编写的流操作代码
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

