Cron 表达式:写对,且知道它什么时候会坑你
从自然语言需求反推表达式,并检查时区、夏令时、月末、重入四类坑。
提示词(整段复制)
你是运维工程师。请把下面的自然语言需求翻成 cron 表达式,并做风险检查。
需求描述:{{需求}}
运行环境:{{环境与时区}}
任务耗时:{{任务耗时}}
是否允许多实例部署:{{多实例}}
输出要求:
1. **表达式**:给出 cron(5 段)与 Quartz(6 段)两种写法,标注差异。
2. **逐段解释**:每个字段的值意味着什么,用一句话说明(不要只给表格)。
3. **四类坑逐个检查**:
① 时区:容器/服务器/数据库时区是否一致,不一致时怎么处理;
② 夏令时:所在时区是否有 DST,跳变那一小时任务会怎样;
③ 月末/闰年:`每月的 31 日` 在 2 月会怎样,`每 30 分钟` 与 `每小时的第 30 分` 的区别;
④ 重入:任务耗时超过间隔时会怎样,多实例部署会不会重复执行。
4. **验证方法**:给出命令,列出未来 5 次触发时间,确认与预期一致。
5. **兜底建议**:加锁、超时、失败重试分别怎么做。
约束:
- 如果需求本身有歧义(如「每月初」),先列出 2 种理解让你选,不要擅自决定。复制时把 {{变量}} 换成你自己的内容;变量名不要改,改了模型容易把它当普通文字。
要替换的变量
实操建议
- 「最后一个工作日」用 cron 表达不了,必须靠脚本判断——要求模型明确指出这一点
- 容器时区与业务时区不一致,是最常见的「时间差 8 小时」来源
常见问题
cron 能表达「每月最后一个工作日」吗?
不能。只能每天跑一次,在脚本里判断「今天是不是本月最后一个工作日」,不是就直接退出。
多实例怎么避免重复执行?
分布式锁(Redis SETNX 带过期时间)或数据库唯一约束,二者选一,别靠「只在一台机器上配 cron」。
