Spring Scheduling定时任务午夜后停止运行问题求助
问题描述
配置的定时任务通过@Scheduled(cron = "0 * * ? * *")实现每分钟执行,下午5点到23:59日志打印正常,最后一条日志出现在00:00,但之后任务停止运行。仅周五到周六出现该问题,周六到周日、周日到周一均正常。启动时收到以下警告:
More than one TaskExecutor bean found within the context, and none is named 'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly as an alias) in order to use it for async processing: [XyzThreadPoolTaskScheduler, ZxyThreadPoolTaskScheduler]
排查思路
时区与夏令时排查
Spring的@Scheduled默认使用服务器本地时区,部分地区周五到周六可能涉及夏令时切换,导致cron表达式解析的下一次执行时间异常。可以显式指定时区(如@Scheduled(cron = "0 * * ? * *", zone = "Asia/Shanghai")),验证问题是否复现。00:00任务的完整执行日志检查
虽然日志打印了Stop Xyz,但后续的资源清理、数据库操作、外部调用等步骤可能在日志之后抛出未捕获异常,导致线程终止。检查应用错误日志、GC日志,确认周五午夜是否存在内存溢出、线程死锁、资源耗尽(如数据库连接池耗尽)的情况。ThreadPoolTaskScheduler冲突修复
启动警告提示存在两个TaskExecutor bean,Spring无法确定默认异步执行器。若任务内部包含异步操作,可能因找不到默认执行器导致异常。解决方式:将其中一个ThreadPoolTaskScheduler标记为@Primary,或命名为taskExecutor,再观察周五任务运行状态。系统级维护操作排查
确认周五午夜是否有服务器重启、应用部署、日志切割、资源回收脚本等运维操作,这类操作可能中断应用进程或暂停调度器。查看服务器系统日志、运维记录,核对00:00左右的操作记录。调度器线程状态验证
周五午夜后,通过jstack、jconsole等JVM工具查看两个ThreadPoolTaskScheduler的线程状态,检查是否有线程阻塞、挂起,或调度器本身是否已停止工作。同时确认Spring上下文是否在午夜后出现异常,导致调度器bean被销毁。业务逻辑依赖资源检查
任务中的业务代码可能依赖仅在工作日可用的资源(如周五午夜后外部服务停机、数据库备份锁表),导致任务执行卡住,占用线程池线程,后续任务无法调度。模拟周五午夜环境,复现任务执行流程,排查资源依赖问题。
内容的提问来源于stack exchange,提问作者Dafik

