秒级定时任务速查手册:核心语法与实用示例
秒级定时任务如何优雅地实现?本文适合收藏备查,涵盖核心语法与常用示例。
核心语法
Cron 表达式格式
| 位置 | 允许的值 | 允许的特殊字符 | 说明 |
|---|---|---|---|
| 秒 | 0-59 | * / , - |
秒单位 |
| 分 | 0-59 | * / , - |
分钟单位 |
| 小时 | 0-23 | * / , - |
小时单位 |
| 日 | 1-31 | * / , - ? L W |
日期 |
| 月 | 1-12 | * / , - |
月份 |
| 周 | 0-7 | * / , - ? L # |
周几 |
| 年 | (可选) | * / , - |
年份 |
特殊字符说明
| 字符 | 说明 |
|---|---|
* |
通配符,表示该位置的任意值 |
, |
分隔符,表示多个值 |
- |
范围符,表示一个范围 |
/ |
步长符,表示从某个值开始,每隔多少执行一次 |
? |
占位符,表示该位置不指定值 |
L |
表示月的最后一天或周的最后一天 |
W |
表示最接近指定日期的工作日 |
# |
表示月的第几周的周几 |
常用示例
每分钟的第 30 秒执行
shell
30 * * * * *
每 5 秒执行一次
shell
0-59/5 * * * * *
10:30:30 每天执行
shell
30 30 10 * * *
10:30:30 每周一和周五执行
shell
30 30 10 * * 1,5
10:30:30 每月最后一个工作日执行
shell
30 30 10 L * *
10:30:30 每月的第 3 周的周三执行
shell
30 30 10 ? * 3#3
每天 10:30:30 到 10:30:45 之间的每一个 5 秒执行一次
shell
30-45/5 30 10 * * *
每天 10:00:00 到 10:00:59 之间的所有秒执行
shell
0-59 0 10 * * *
每天 10:00:00 到 10:00:59 之间的所有秒,但只在周一执行
shell
0-59 0 10 * * 1
每天 10:00:00 到 10:00:59 之间的所有秒,但只在每月的 1 号执行
shell
0-59 0 10 1 * *
每天 10:00:00 到 10:00:59 之间的所有秒,但只在每年的 1 月 1 日执行
shell
0-59 0 10 1 1 *
Java 实现
使用 Quartz
java
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
public class SecondlyJob implements Job {
public void execute(JobExecutionContext context) {
System.out.println("Job executed at " + new Date());
}
public static void main(String[] args) throws SchedulerException {
// 创建调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 创建任务
JobDetail job = JobBuilder.newJob(SecondlyJob.class)
.withIdentity("job1", "group1")
.build();
// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
// 调度任务
scheduler.scheduleJob(job, trigger);
// 启动调度器
scheduler.start();
}
}
使用 Spring Scheduler
java
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
@Scheduled(cron = "0/5 * * * * ?")
public void runEvery5Seconds() {
System.out.println("Task executed at " + new Date());
}
}
Python 实现
使用 APScheduler
python
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def job():
print("Job executed at", datetime.now())
scheduler = BlockingScheduler()
# 每 5 秒执行一次
scheduler.add_job(job, 'cron', second='0/5')
scheduler.start()
使用 Celery
python
from celery import Celery
from datetime import timedelta
app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def hello():
print("Hello World!")
# 定义定时任务
app.conf.beat_schedule = {
'add-every-5-seconds': {
'task': 'tasks.hello',
'schedule': timedelta(seconds=5),
},
}
Node.js 实现
使用 Node-cron
javascript
const cron = require('node-cron');
const moment = require('moment');
cron.schedule('0/5 * * * * *', () => {
console.log('Running at', moment().format('YYYY-MM-DD HH:mm:ss'));
});
使用 Agenda
javascript
const Agenda = require('agenda');
const mongoose = require('mongoose');
const agenda = new Agenda({ db: { address: 'mongodb://localhost/test' } });
agenda.define('hello', (job, done) => {
console.log('Hello World!');
done();
});
agenda.every('0/5 seconds', 'hello');
agenda.start();
Go 实现
使用 Robfig/cron
go
package main
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
)
func main() {
c := cron.New()
// 每 5 秒执行一次
_, err := c.AddFunc("0/5 * * * * *", func() {
fmt.Println("Running at", time.Now())
})
if err != nil {
panic(err)
}
c.Start()
select {}
}
使用 Cronexpr
go
package main
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
"github.com/err0r500/go-cronexpr"
)
func main() {
expr := cronexpr.Parse("0/5 * * * * *")
ticker := cronexpr.NewTicker(expr)
for {
select {
case t := <-ticker.C:
fmt.Println("Running at", t)
}
}
}
实用工具推荐
实现秒级定时任务时,Cron 表达式是关键。但手写 Cron 表达式容易出错,推荐使用 Hey Cron 的 Cron 表达式生成器,中文描述秒转 cron,省时省力:
- Cron 表达式生成器:中文描述秒转 cron,快速生成复杂表达式
- 正则表达式生成器:轻松生成正则表达式,支持多种场景
- 中英互译:快速翻译文本,支持多种语言
- JSON 格式化:美化 JSON 格式,便于阅读和调试
- Base64 编码解码:在线编码和解码 Base64 字符串
- 时间戳转换:轻松转换时间戳与日期时间
- JWT 解析:解析 JWT 令牌,查看其中的内容