你有没有遇到过这种事:明明写的是早上9点执行,结果任务在下午5点才跑起来。查了半天代码,逻辑没问题,最后发现是cron表达式在时区上摆了你一道。
cron是Unix系统里最经典的定时任务调度器,它的表达式语法早就跑出了Unix的圈子——CI流水线、云调度器、任务队列,几乎都认这套写法。语法很紧凑,紧凑到稍微写错一个字符,任务就会在错误的时间悄悄执行,甚至根本不执行。
![]()
五个字段,从左到右读
一个标准的cron表达式由五个空格分隔的字段组成,从左到右依次是:分钟、小时、日、月、星期。每个字段的取值范围是固定的:
- 分钟:0-59
- 小时:0-23
- 日:1-31
- 月:1-12
- 星期:0-6,其中0代表周日
当当前时间同时匹配这五个字段时,任务就会执行。星号(*)表示该字段的"所有可能值"。所以* * * * *的意思就是每分钟都跑一次。
四个特殊字符,撑起所有写法
cron表达式的灵活性全靠四个特殊字符:
- :匹配该字段的所有值
- :分隔列表,比如 1,15 表示第1天和第15天
- :定义范围,比如 1-5 在星期字段里就是周一到周五
- :定义步长,比如 */15 表示每15个单位,10-40/10 表示10、20、30、40
把这四个字符组合起来,就能覆盖绝大多数调度需求。几个常见写法可以直接记下来:
- */5 * * * *:每5分钟执行一次
- :每小时整点执行
- 0 9 * * 1-5:工作日早上9点执行
- 30 2 * * 0:每周日凌晨2点30分执行
- 0 0 1 * *:每月1号午夜执行
- 0 0 1 1 *:每年1月1号午夜执行一次
- 15 14 1 * *:每月1号下午2点15分执行
时区:最容易踩的坑
cron运行在机器或服务所在的时区,而这个时区非常常见地就是UTC。你写"早上9点",它可能指的是UTC早上9点,而不是你本地时间的早上9点。云调度器通常允许显式设置时区,但在你假设之前,先去确认一下。
这就是为什么会出现"我写的9点,怎么下午5点才跑"——如果你的本地时间比UTC快8小时,UTC的9点正好是你的下午5点。反过来也一样,你以为任务没跑,其实它在你睡觉的时候就跑完了。
日和星期同时限制,结果可能出乎意料
在经典的Vixie cron里,如果你同时限制了"日"和"星期"两个字段,任务会在两者任意一个匹配时执行,而不是两个都匹配才执行。
举个例子:0 0 13 * 5会在每个月的13号执行,也会在每个周五执行,而不是只在"13号且是周五"的时候执行。也就是说,它不会只命中"13号星期五"这种组合。其他调度器的行为可能不一样,用之前先读文档。
方言差异:不是所有cron都长一样
cron表达式看起来统一,实际上不同系统之间存在方言差异:
- 有些系统(比如Quartz、Spring、AWS EventBridge)会额外增加秒字段或年份字段,表达式变成六个或七个字段
- 有些支持 MON、JAN 这样的名称,以及 @daily、@hourly 这类快捷写法,有些则不支持
- L、W、# 这些字符(分别表示最后一天、最近的工作日、第几个星期几)只存在于部分方言中
所以当你从一个系统复制表达式到另一个系统时,不能想当然地认为它能按原意工作。
夏令时:一年两次的隐形陷阱
在实行夏令时的本地时区里,被跳过的那一个小时中安排的任务可能不会执行,而被重复的那一个小时中安排的任务可能会执行两次。用UTC来调度可以完全避开这个问题。
这也是为什么很多生产环境的调度器默认用UTC——不是为了省事,是为了避开夏令时带来的不确定性。
部署前先做一次 sanity check
把表达式粘贴到一个解析器里,读出它的自然语言翻译。如果翻译出来的意思和你想的不一样,在它于生产环境里悄悄跑错时间之前,先改掉。
这一步花不了几秒钟,但能省掉一次半夜被叫起来排查"任务为什么没跑"的经历。
几个高频问题
*/5 * * * * 是什么意思?每5分钟执行一次。分钟字段里的 */5 是步长为5,其他字段都是通配符。
怎么让任务每天午夜执行?用 0 0 * * *。也就是分钟0、小时0、每天、每月、每周的每一天。
cron用的是UTC还是本地时间?用的是运行它的机器或调度服务所在的时区。很多服务器和云调度器默认UTC,所以该确认的时候要确认,该显式设置时区的时候就显式设置。
五字段和六字段cron有什么区别?标准Unix cron是五个字段,从分钟到星期。有些调度器会在前面加一个秒字段,或者在后面加一个年份字段,所以用之前一定要确认你的工具期望哪种格式。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.