Spring Cron六段格式
Spring的Cron表达式从秒开始,共6段:秒、分钟、小时、日期、月份和星期。它看起来接近Quartz,但不应默认所有Quartz扩展都能在每个Spring版本中完全一致地使用。
@Scheduled(cron = "0 0 9 ? * MON-FRI", zone = "Asia/Shanghai")
public void generateDailyReport() {
// 工作日上午9点执行
} | 位置 | 字段 | 示例 |
|---|---|---|
| 1 | 秒 | 0 |
| 2 | 分钟 | 0/5 |
| 3 | 小时 | 9-18 |
| 4 | 日期 | ? |
| 5 | 月份 | * |
| 6 | 星期 | MON-FRI |
Spring @Scheduled常用示例
| 表达式 | 含义 |
|---|---|
0 0/5 * * * ? | 每5分钟 |
0 0 2 * * ? | 每天凌晨2点 |
0 0 9 ? * MON-FRI | 工作日上午9点 |
0 30 9 ? * MON#2 | 每月第二个星期一9:30 |
0 0 18 L * ? | 每月最后一天18点 |
不要忽略zone时区
如果没有显式配置 zone,任务会使用应用运行环境的默认时区。开发机、Docker镜像、Kubernetes节点和生产服务器可能并不一致。
对中国业务建议明确写出
zone = "Asia/Shanghai",并在监控中记录实际触发时间和业务日期。表达式正确不等于任务可靠
- 默认调度线程可能被长任务占用,应根据业务配置独立线程池。
- 多实例部署会让每个实例都执行一次,需要分布式锁或集中式调度。
- 任务异常必须记录结果并通知,不能只依赖应用日志。
- 涉及补偿、重试和幂等时,应把一次调度与一次业务执行分开记录。
- 重要任务可接入心跳监控,及时发现服务未启动或调度漏执行。
Spring Cron与Linux Crontab区别
最明显的区别是Spring第一段为秒,而Linux第一段为分钟。Spring通常写在应用代码中,随应用生命周期运行;Crontab由操作系统调度,与应用框架无关。迁移表达式时必须先选择目标执行器。