cron格式:
分 时 日 月 周
每隔5分钟执行1次: /5 * echo hello > /tmp/x.log
每隔1-5分钟执行1次: 1-5 echo hello > /tmp/x.log
每天10点整、22点整执行1次: 0 10,22 * echo hello > /tmp/x.log
每隔1-5分钟执行1次: 1-5 echo hello > /tmp/x.log
Parse():解析与校验Cron表达式
Next():根据当前时间,计算下次调度时间
package main
import (
"fmt"
"github.com/gorhill/cronexpr"
"time"
)
func main() {
var (
expr *cronexpr.Expression
err error
now time.Time
nextTime time.Time
)
//每隔5分钟执行一次(这个库支持7位,精确到秒、年)
if expr, err = cronexpr.Parse("*/5 * * * * * *"); err != nil {
fmt.Println(err)
return
}
//当前时间
now = time.Now()
//下次调度时间
nextTime = expr.Next(now)
//等待这个定时器超时
time.AfterFunc(nextTime.Sub(now), func() {
fmt.Println("被调度了:", nextTime)
}) //下次时间减去当前时间
time.Sleep(10 * time.Second)
}
调用一个cron
输出:被调度了: 2019-04-19 17:00:30 +0800 CST
package main
import (
"fmt"
"github.com/gorhill/cronexpr"
"time"
)
//代表一个任务
type CronJob struct {
expr *cronexpr.Expression
nextTime time.Time //expr.Next(time.Now())就可以得到下一次调度时间
}
func main() {
//需要有1个调度协程,它定时检查所有Cron任务,谁过期了就执行谁
var (
cronJob *CronJob
expr *cronexpr.Expression
now time.Time
scheduleTable map[string] *CronJob //key:任务名字,
)
scheduleTable = make(map[string]*CronJob)
//当前时间
now = time.Now()
//定义第一个cronjob
expr = cronexpr.MustParse("*/5 * * * * * *")
cronJob = &CronJob{
expr: expr,
nextTime: expr.Next(now),
}
//任务注册到了调度表
scheduleTable["job1"] = cronJob
//定义第二个cronjob
expr = cronexpr.MustParse("*/5 * * * * * *")
cronJob = &CronJob{
expr: expr,
nextTime: expr.Next(now),
}
//任务注册到了调度表
scheduleTable["job2"] = cronJob
//启动调度协程
go func() {
var (
jobName string
cronJob *CronJob
now time.Time
)
//定时检查任务调度表是否有到期的
for {
now = time.Now()
for jobName, cronJob = range scheduleTable {
//判断是否过期(如果下次调度时间早于等于当前时间,说明已经过期了)
if cronJob.nextTime.Before(now) || cronJob.nextTime.Equal(now) {
//启动一个协程,执行这个任务
go func(jobName string) {
fmt.Println("执行:", jobName)
}(jobName)
//计算下一次调度时间
cronJob.nextTime = cronJob.expr.Next(now)
fmt.Println(jobName, "下次执行时间:", cronJob.nextTime)
}
}
select {
//睡眠100毫秒(不让它占用过多cpu)
case <- time.NewTimer(100 * time.Millisecond).C: //将在100毫秒可读,返回
}
}
}()
time.Sleep(100 * time.Second)
}
调用多个cron,按时间间隔输出:
执行: job1
job1 下次执行时间: 2019-04-19 17:31:20 +0800 CST
job2 下次执行时间: 2019-04-19 17:31:20 +0800 CST
执行: job2
执行: job1
job1 下次执行时间: 2019-04-19 17:31:25 +0800 CST
执行: job2
job2 下次执行时间: 2019-04-19 17:31:25 +0800 CST
执行: job1
job1 下次执行时间: 2019-04-19 17:31:30 +0800 CST
job2 下次执行时间: 2019-04-19 17:31:30 +0800 CST
执行: job2
......