为什么并发用户数超过13时karate-gatling无日志输出?
Karate-Gatling高并发下simulation.log写入失败问题解答
核心原因
这是典型的多线程竞态条件触发的问题,Karate-Gatling早期版本(1.4.0以前)的日志写入模块存在明确的并发安全缺陷,对应触发场景与描述的完全一致:
- 底层
SimulationLogWriter对simulation.log的写入操作未加线程锁,多并发场景下多个线程同时争抢文件句柄、写入缓冲区,会直接导致缓冲区数据丢失、文件流异常关闭。通常消费级设备的默认IO线程池大小为CPU核心数*2,大多在12-16区间,当并发数超过14时正好触发阈值,线程争抢概率呈指数级上升,并发越高,缓冲区溢出、写入流异常的时间点就越早。 - 默认的日志刷盘策略为异步缓冲写入,高并发下日志生产速度远高于磁盘写入速度,缓冲区被占满后新产生的日志会被直接丢弃,不会进入写入队列。
- Gatling引擎的回压机制会在系统负载过高时优先保障压测请求调度,主动暂停非核心的日志写入任务,持续高并发场景下日志写入任务始终无法获取CPU时间片,全程无日志输出。
修复方案
- 升级到Karate 1.4.0及以上正式版本,官方已修复该日志写入的竞态缺陷
- 减少非必要日志输出:关闭请求体、响应体全量打印,仅保留请求状态、错误信息等核心字段,降低单条日志体积
- 修改logback配置,开启同步刷盘、加大缓冲区容量,参考配置如下:
<appender name="SIMULATION_FILE" class="ch.qos.logback.core.FileAppender"> <file>simulation.log</file> <immediateFlush>true</immediateFlush> <bufferSize>10MB</bufferSize> <encoder> <pattern>%d{ISO8601} %msg%n</pattern> </encoder> </appender>
- 启动压测时添加JVM参数调整Gatling日志写入阈值:
-Dgatling.core.dataWriter.timeout=30000 -Dgatling.core.dataWriter.maxBatchSize=2000
内容的提问来源于stack exchange,提问作者Milan Smolík
相关产品推荐
相关产品推荐

