Spring Boot应用中Cron表达式未按预期运行,求可用配置示例
Spring Boot Cron表达式配置及调度异常修复
可正常生效的Cron使用示例
Spring Boot内置的cron表达式支持6位或7位字段,顺序为秒 分 时 日 月 周 [年],其中日和周字段不能同时设置为*,需用?标记其中一个不指定,避免语义冲突。
1. 配置文件(application.yml)中定义
先在配置文件中声明cron配置项:
schedule: # 每隔10分钟执行一次的cron表达式 cron: 0 0/10 * * * ?
在业务代码中取值使用即可:
@Scheduled(cron = "${schedule.cron}") public void executeScheduledTask() { // 你的业务逻辑 }
2. Spring Integration Poller 配置示例
你使用的xml配置的正确写法如下,修正cron表达式的语义冲突:
<int:poller max-messages-per-poll="1" cron="0 0/10 * * * ?" task-executor="commonThreadPoolTaskExecutor" />
任务执行5次后停止的问题修复
触发原因
绝大多数场景下该问题和cron表达式无关,由绑定的线程池配置异常导致:
- 你配置的
commonThreadPoolTaskExecutor核心线程数小于等于5,且非核心线程存活时间设置过短、任务拒绝策略为丢弃任务,当5次任务执行后没有空闲线程,后续任务直接被拒绝执行 - 调度任务执行过程中抛出未捕获的异常,没有异常兜底逻辑,导致调度线程被销毁后无法重建
修复方案
- 调整线程池配置,参考示例如下:
@Bean public ThreadPoolTaskExecutor commonThreadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 核心线程数至少设置为大于等于单次调度同时运行的任务数 executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(100); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("common-schedule-"); // 拒绝策略设置为 caller_runs,避免任务被直接丢弃 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; }
- 在调度任务的业务逻辑外层增加try-catch兜底,避免未捕获异常销毁线程:
public void yourTaskLogic() { try { // 原有业务逻辑 } catch (Exception e) { // 打印异常日志即可,不要向上抛出 log.error("调度任务执行异常", e); } }
内容的提问来源于stack exchange,提问作者Anumol
相关产品推荐
相关产品推荐

