Spring Batch Repeat Template卡顿超3分钟问题排查求助
看了你提供的RepeatTemplate关键日志:
2018-03-14 10:18:13.127 [WorkManager.DefaultWorkManager : 441] DEBUG o.s.b.repeat.support.RepeatTemplate - [user1] - Repeat operation about to start at count=81
2018-03-14 10:21:25.178 [WorkManager.DefaultWorkManager : 441] DEBUG o.s.b.repeat.support.RepeatTemplate - [user1] - Repeat operation about to start at count=82
还有你给出的Spring Batch配置(使用DefaultResultCompletionPolicy单条记录chunk、REQUIRES_NEW独立事务),再结合任务已稳定运行2年的背景,咱们可以从特定数据处理、事务提交、容器调度、系统资源这几个方向来定位问题:
一、第81条数据的处理阻塞
你的DefaultResultCompletionPolicy会让每个chunk仅处理1条记录,所以count=81到count=82的间隔,就是第81条数据从读取到事务提交的完整周期。这是最有可能的原因:
- 读取环节:这条数据可能触发了数据库行锁等待(比如其他业务事务长时间持有该数据的锁)、或者包含特殊字段(如超大文本、异常编码值)导致关联查询/解析变慢;
- 写入环节:文件存储出现临时IO挂起(比如WAS挂载的磁盘阵列缓存刷新、存储临时故障),或者这条数据触发了未覆盖到的边缘校验逻辑,导致写入时出现长时间等待。
二、事务提交阶段的延迟
你的tasklet配置了propagation="REQUIRES_NEW",意味着每条记录都会开启独立事务并提交。3分钟的延迟很可能出在事务提交环节:
- 数据库redo log刷盘延迟:如果数据库所在存储IO突然饱和(比如同期有备份、批量导入任务),事务提交需要等待日志刷盘完成,会导致长时间阻塞;
- 数据库连接池临时耗尽:虽然内存充足,但如果数据库连接池在这个时段没有可用连接,事务提交时可能会等待连接释放(可以检查WAS的数据库连接池监控日志)。
三、WAS WorkManager的线程调度瓶颈
你使用的是WorkManager.DefaultWorkManager线程,虽然日志里线程ID未变化,但可能存在调度层面的阻塞:
- 线程池资源抢占:如果DefaultWorkManager的线程池在这个时段被其他高优先级任务占满,你的任务线程可能被挂起等待调度;
- WAS事务协调器临时异常:WAS与数据库之间的网络短暂抖动、或者事务管理器内部资源冲突,也可能导致事务处理延迟。
四、系统层面的资源抢占
排除应用和数据库层面后,要检查服务器的系统资源状态:
- CPU/磁盘IO峰值:比如同期有系统备份、其他批量任务运行,导致CPU被占满或磁盘IO达到100%,你的任务线程无法获得足够资源执行;
- JVM非GC操作:虽然verboseGC显示有1G空闲内存,但JIT编译、类加载等操作偶尔也会导致线程短暂挂起,但一般不会持续3分钟,这个可能性相对较低。
具体排查步骤
- 定位异常数据:找到任务执行时的第81条记录,检查数据内容、关联数据是否存在异常;
- 检查数据库日志:对应10:18:13~10:21:25时间段,查看是否有锁等待、慢查询、事务超时的日志;
- 监控WAS资源:查看WorkManager线程池的实时状态、数据库连接池的使用率;
- 补充业务日志:在
bulkPaymentTableReader和bulkPaymentFileWriter的方法前后添加日志,记录每条数据的处理开始/结束时间,下次出现时可精准定位是读还是写环节出问题; - 检查系统监控:查看服务器的CPU、磁盘IO、网络流量的历史监控数据,是否有异常峰值。
内容的提问来源于stack exchange,提问作者William Stevenson

