在linux里可以通过crontab -e或者vi /etc/crontab编辑定时任务,区别在于后者只有root用户可以,还可以指定shell环境,不建议修改,修改前建议备份,前者任何用户都可以使用,两者修改后都不用修改自动重启。
1 linux crontab定时任务
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
2 golang crontab定时任务
2.1 安装使用
2.1.1 安装
go get github.com/robfig/cron/v3@v3.0.0
2.1.2 导入
import "github.com/robfig/cron/v3"
2.2 时间规则
2.2.1 标准时间规则
# .------------------second (0 - 59)
# | .---------------- minute (0 - 59)
# | | .------------- hour (0 - 23)
# | | | .---------- day of month (1 - 31)
# | | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun
# | | | | | |
# * * * * * * user-name command to be executed
package crontab
import "github.com/robfig/cron"
func CronExec() {
spec := "*/2 * * * * ?" //每2s执行一次
spec := "0 5 10 * * ?" //每天早上10:05:00执行一次
spec := "* * 10 * * ?" //每天10点开始的一个小时一直在执行
spec := "* 1-59/10 * * * ?" //每天1分到59分每10分钟执行一次
c := cron.New()
id,err := c.AddFunc(spec, func()) {
crontab()
}
if err != nil {
fmt.Sprintf("crontab exec error: %v with id: %v", err, id)
}
c.Start()
return c
func crontab() {
fmt.Sprint("crontab exec...")
}
package main
import crontab
func main() {
//执行任务代码
xxx
go func() {
CronExec()
}()
}
2.2.2 预定义时间规则
为了方便使用,cron预定义了一些时间规则:
- @yearly:也可以写作@annually,表示每年第一天的 0 点。等价于0 0 1 1 *;
- @monthly:表示每月第一天的 0 点。等价于0 0 1 * *;
- @weekly:表示每周第一天的 0 点,注意第一天为周日,即周六结束,周日开始的那个 0 点。等价于0 0 * * 0;
- @daily:也可以写作@midnight,表示每天 0 点。等价于0 0 * * *;
- @hourly:表示每小时的开始。等价于0 * * * *。
func main() {
c := cron.New()
c.AddFunc("@hourly", func() {
fmt.Println("Every hour")
})
c.AddFunc("@daily", func() {
fmt.Println("Every day on midnight")
})
c.AddFunc("@weekly", func() {
fmt.Println("Every week")
})
c.Start()
for {
time.Sleep(time.Second)
}
}
注意:这样使用一个 cron.New() 的定时任务,执行的每个方法是顺序执行的,也就是说并不是同一时刻开始执行。
2.2.3 固定时间间隔
cron支持固定时间间隔,格式为:
@every <duration>
含义为每隔duration触发一次。<duration>会调用time.ParseDuration()函数解析,所以ParseDuration支持的格式都可以。例如1h30m10s。
2.2.4 时区
默认情况下,所有时间都是基于当前时区的。当然我们也可以指定时区,有 2 两种方式:
在时间字符串前面添加一个CRON_TZ= + 具体时区,具体时区的格式在之前carbon的文章中有详细介绍。东京时区为Asia/Tokyo,纽约时区为America/New_York;
创建cron对象时增加一个时区选项cron.WithLocation(location),location为time.LoadLocation(zone)加载的时区对象,zone为具体的时区格式。或者调用已创建好的cron对象的SetLocation()方法设置时区。
func main() {
nyc, _ := time.LoadLocation("America/New_York")
c := cron.New(cron.WithLocation(nyc))
c.AddFunc("0 6 * * ?", func() {
fmt.Println("Every 6 o'clock at New York")
})
c.AddFunc("CRON_TZ=Asia/Tokyo 0 6 * * ?", func() {
fmt.Println("Every 6 o'clock at Tokyo")
})
c.Start()
for {
time.Sleep(time.Second)
}
}
2.3 常用方法
2.3.1 New()
会根据本地时间创建一个新(空白)的计划任务实例
// 创建一个默认的cron对象
cron.New()
// 自定义解析器
cron.New(cron.WithSeconds())
// Seconds field, optional
cron.New(cron.WithParser(cron.NewParser(
cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor,
)))
2.3.2 AddJob()
// 有两个参数,第一个参数可以是cron表达式或者预定义时间表,第二个Job
func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error)
// Job是一个接口,有一个Run方法
type Job interface {
Run()
}
2.3.3 AddFunc()
会向计划任务实例中添加一个回调函数,按指定时间表执行回调函数。
// 有两个参数,第一个参数可以是cron表达式或者预定义时间表,第二个传入一个函数,就是要执行的任务
// 会返回一个Id和error
// 会把传入的cmd func转成FuncJob。FuncJob实现了Job接口
func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) {
return c.AddJob(spec, FuncJob(cmd))
}
2.3.4 Start()
调用start方法开始执行任务。