cronNestJS

Cron 是什么?从 0 到精通这门“时间语言”

Cron是一种用于定义定时任务执行时间的表达式语言,广泛应用于自动化任务如数据清理、报表生成等场景。文章介绍了Cron的两种格式(Unix标准5字段和扩展6字段),重点说明NestJS必须使用6字段格式。详细解析了Cron的语法结构,包括特殊符号(*,-,/)的含义和常见表达式示

2025-10-17·阅读约 10 分钟·计算中...

⏰ Cron 是什么?从 0 到精通这门“时间语言”

「每天凌晨 2 点自动清理数据库」「每 15 分钟同步缓存」「每周一早上 8 点发送报告」——这些自动化任务背后都有一个低调而强大的角色:Cron


一、Cron 是什么?

Cron 是一种用于描述“任务在什么时间执行”的表达式语言。它本身不执行任务,只负责定义 何时 触发,由调度器(Scheduler)在匹配的时间点调用你的代码。

你可以把它理解为“时间的 DSL(领域特定语言)”。


二、为什么要懂 Cron?

  • 定时清理、数据归档、报表生成、缓存刷新、外部同步等后端任务都依赖它。
  • 现代框架(NestJS、Spring、Django 等)与云平台(Kubernetes、Serverless)普遍支持 Cron。

在 NestJS 中只需一行即可创建定时任务:

import { Cron } from '@nestjs/schedule';

@Cron('0 0 2 * * *', { timeZone: 'UTC' })
handleCron() {
  console.log('每天凌晨 2 点执行任务');
}

三、Cron 表达式的两类格式

1) 标准 Unix(5 字段)

分 时 日 月 周

示例:

0 2 * * *

含义:每天 02

执行。


2) 扩展格式(6 字段,NestJS 使用)

秒 分 时 日 月 周

示例:

0 0 2 * * *

含义:每天 02:00

执行。

NestJS 必须使用 6 字段
❌ 用 5 字段会被错位解析,导致时间混乱。


四、字段结构图解(6 字段)

┌──────────── 秒 (0–59)
│ ┌────────── 分 (0–59)
│ │ ┌──────── 时 (0–23)
│ │ │ ┌────── 日 (1–31)
│ │ │ │ ┌──── 月 (1–12)
│ │ │ │ │ ┌── 周 (0–7,0/7=周日)
│ │ │ │ │ │
0  0  2  *  *  *   → 每天 02:00:00 执行

五、语法速查

符号 含义 示例
* 任意值 * * * * * * → 每秒
, 多个值 0 0 8,20 * * * → 8 点和 20 点
- 范围 0 0 9-17 * * 1-5 → 工作日 9–17 点整点
/ 步长 0 */15 * * * * → 每 15 分钟

六、常见表达式(6 字段)

表达式 含义 执行时间
0 0 2 * * * 每天凌晨 2 点 02:00
0 30 3 * * * 每天 3
03:30
0 0 */6 * * * 每 6 小时 00
、06
、12
、18
0 0 8 * * 1-5 工作日早 8 点 周一至周五 08:00
0 0 0 1 1 * 每年元旦 01-01 00:00
0 */15 * * * * 每 15 分钟 00、15、30、45 分

七、NestJS 最佳实践

1) 环境变量(带引号更安全)

# .env.production
CLEANUP_ENABLED=true
CLEANUP_CRON="0 0 2 * * *"
CLEANUP_TIMEZONE=UTC

2) 配置类

export class RateLimitConfig {
  static readonly CLEANUP = {
    ENABLED: process.env.CLEANUP_ENABLED === 'true',
    CRON: process.env.CLEANUP_CRON || '0 0 2 * * *',
    TIMEZONE: process.env.CLEANUP_TIMEZONE || 'UTC',
  };
}

3) Service 中注册任务

@Cron(RateLimitConfig.CLEANUP.CRON, {
  name: 'cleanup-job',
  timeZone: RateLimitConfig.CLEANUP.TIMEZONE,
})
async cleanup() {
  if (!RateLimitConfig.CLEANUP.ENABLED) return;
  // 你的清理逻辑...
}

八、常见误区对比

错误写法 问题 正确写法
0 2 * * * 5 字段导致错位解析 "0 0 2 * * *"
0 0 2 * * *(无引号) shell 可能拆分空格 "0 0 2 * * *"
未指定时区 不同服务器表现不一致 timeZone: 'UTC''Asia/Shanghai'

九、时区(TimeZone)

  • Cron 默认用系统时区;云/容器环境多为 UTC
  • 建议:开发用 Asia/Shanghai 方便本地验证;生产统一用 UTC
@Cron('0 0 2 * * *', { timeZone: 'Asia/Shanghai' })
时区 说明
UTC 协调世界时(生产推荐)
Asia/Shanghai 北京时间(UTC+8)
America/New_York 美东时间
Europe/London 伦敦时间

十、验证与调试

本地验证

npm i cron-parser
import * as parser from 'cron-parser';

const it = parser.parseExpression('0 0 2 * * *');
console.log('Next 5 runs:');
for (let i = 0; i < 5; i++) console.log(it.next().toString());

在线工具


十一、时间轴示意

时间线(示例:0 0 2 * * *):
00:00 ──────────────┬─────────────┬─────────────┬─────────────
                     └─ 02:00:00(每天)

十二、它属于哪个类别?

归属领域: 任务调度(Job Scheduling)/ 系统自动化调度。
技术栈层级: 后端基础设施能力,介于应用层系统运维之间。
与数据库关系: 常用于触发数据库的备份/清理/归档,但它本身不是数据库技术。

知识图谱定位:

软件工程
 ├─ 后端开发
 │   ├─ Web 框架(NestJS、Spring)
 │   ├─ 任务队列(BullMQ、Celery)
 │   └─ 定时任务(Cron / @nestjs/schedule)✅
 ├─ 系统运维
 │   ├─ 进程管理(pm2、systemd)
 │   └─ Cron 守护进程(crond)✅
 └─ 数据库管理
     └─ 借助 Cron 触发备份/清理/归档(间接)⚙️

十三、总结

  • Cron 是“时间的语言”,只定义“何时执行”,不负责“执行什么”。
  • NestJS 使用 6 字段(秒 分 时 日 月 周),务必与 5 字段区分。
  • 时区要明确,生产推荐统一使用 UTC
  • 写完要验证cron-parser / 在线工具)。

掌握 Cron,你就掌握了让系统按时自驱的能力。愿每个自动任务都稳准达!


延伸阅读

订阅 FreeMac

每周精选:Mac 高效技巧、免费替代付费软件、开发者工具推荐。用对你的 MacBook,省钱 + 提效。