Spring @Scheduled fixedRate 重复执行异常问题求助
结合你的场景(Spring Boot 2.1.2.RELEASE,@Scheduled(fixedRate=2000),单次任务耗时<1秒但偶尔每秒触发4-6次),以下是常见的问题根源:
多调度器实例并发运行:
你的Handler类同时标注了@Service和@EnableScheduling,如果该类被Spring上下文多次实例化(比如多模块项目中重复扫描、或存在多个@EnableScheduling注解的类),会生成多个独立的TaskScheduler调度器,每个都会按2秒间隔触发任务,最终叠加出短时间内多次执行的现象。系统时钟跳变导致任务补发:
Spring定时任务依赖系统时钟计算触发时机。如果系统时间突然回退(如NTP时间同步修正),调度器会判定已错过多个任务周期,会一次性补发所有滞后的任务,导致短时间内大量输出"Start iteration"日志。自定义调度线程池配置不当:
默认情况下Spring调度器是单线程的,同一时间仅执行一个任务实例。若项目中自定义了TaskScheduler并配置了多线程池,同时任务执行中出现未捕获异常被调度器忽略(任务被标记为完成),会让调度器在fixedRate间隔下并发触发多个任务,当线程池允许时就会出现频繁执行的情况。Spring Framework版本的已知bug:
Spring Boot 2.1.2对应Spring Framework 5.1.4,该版本的ThreadPoolTaskScheduler存在调度逻辑瑕疵:当任务快速完成且系统负载波动时,可能误判任务周期,导致批量触发任务。后续5.1.5+版本修复了相关时钟计算问题。任务逻辑存在隐式异步操作:
若HTTP请求逻辑使用了异步客户端且未正确阻塞等待响应,会导致handle()方法提前返回,调度器认为任务已完成,提前触发下一次执行。这种情况叠加后,会短时间内触发多次任务。
内容的提问来源于stack exchange,提问作者Alon Baton

