首页 / 文章 / Cron表达式怎么写:五字段还是…

Cron表达式怎么写:五字段还是六字段,星号和斜杠代表什么

定时任务出问题的原因,十有八九出在表达式本身:想的是每天凌晨两点跑一次,写出来的却是每分钟跑一次,日志瞬间被刷爆;或者本来该跑的任务压根没触发,等发现时数据已经缺了几天。Cron 表达式只有短短一截字符串,但每个位置的含义都很严格,写之前值得把它彻底弄明白。

先搞清楚有几个字段

标准 crontab 是五个字段,从左到右依次是分钟、小时、日、月、星期,用空格分隔。很多框架在这个基础上扩展出了六位甚至七位,多出来的通常是秒或者年,比如 Spring 的 @Scheduled 是六位,第一位是秒。动手写之前先确认目标环境用几位,这是最基础也最容易搞混的一点——五位的写法放到六位环境里,含义会整体错位。

四个通配符的含义

星号表示"每一个",放在分钟位就是每分钟。逗号用来列举,比如"1,15,30"表示第 1、15、30 分钟各触发一次。连字符表示范围,"9-18"就是 9 点到 18 点。斜杠表示步长,"*/10"在分钟位表示从 0 分开始每 10 分钟一次,注意它是从范围起点开始数,而不是从当前时间开始数,这个区别会直接影响第一次触发的时刻。

几个高频写法对照

每天凌晨两点整是"0 2 * * *",注意分钟位必须写 0,写成星号就变成两点内每分钟一次。每十分钟一次是"*/10 * * * *"。工作日早上九点是"0 9 * * 1-5",星期字段这里 0 和 7 都表示周日,不同实现略有差异。每月 1 号凌晨是"0 0 1 * *"。写完如果不确定,把表达式里的日期字段对照日期时间转换器核一下时间戳,比凭空想象可靠。

日字段和星期字段的冲突

这是最经典的坑:当日字段和星期字段都写了具体值(都不是星号)时,多数实现按"或"处理,也就是两个条件满足其一就触发。想表达"每月 1 号且必须是周一",直接写两个字段是做不到的,只能在脚本内部再做一次日期判断。反过来,如果想限定某一天,通常的做法是把不需要的字段设成星号,让另一个字段起决定作用。

时区与验证

服务器时区是另一个隐形陷阱:容器默认是 UTC,你按北京时间写的凌晨两点,实际对应的是北京时间上午十点。部署前确认一下运行环境的时区设置,别让备份任务在业务高峰跑起来。最后,任何表达式上线都要看一次执行记录,定时任务没有报错就停在那儿的情况很常见,日志分析可以直接交给网站日志分析工具,跑没跑、跑了几遍,一眼就能看出来。