Cron定时任务
在实际的应用项目中,定时任务的使用是很常见的。你是否有过 Golang 如何做定时任务的疑问,莫非是轮询?
在本文中我们将结合我们的项目讲述 Cron
介绍
我们将使用 cron 这个包,它实现了 cron 规范解析器和任务运行器,简单来讲就是包含了定时任务所需的功能
Cron表达式格式
字段名 | 是否必填 | 允许的值 | 允许的特殊字符 |
分(Minutes) | Yes | 0-59 | * / , - |
时(Hours) | Yes | 0-23 | * / , - |
一个月中的某天(Day of month) | Yes | 1-31 | * / , - ? |
月(Month) | Yes | 1-12 or JAN-DEC | * / , - |
星期几(Day of week) | Yes | 0-6 or SUN-SAT | * / , - ? |
Cron表达式表示一组时间,使用 5 个空格分隔的字段
Cron特殊字符
- 星号(*)
星号表示将匹配字段的所有值 - 斜线(/)
斜线用户 描述范围的增量,表现为 “N-MAX/x”,first-last/x 的形式,例如 3-59/15 表示此时的第三分钟和此后的每 15 分钟,到59分钟为止。即从 N 开始,使用增量直到该特定范围结束。它不会重复 - 逗号(,)
逗号用于分隔列表中的项目,例如,在 Day of week 使用“MON,WED,FRI”将意味着星期一,星期三和星期五 - 连字符(-)
连字符用于定义范围。例如,9 - 17 表示从上午 9 点到下午 5 点的每个小时 - 问号(?)
不指定值,用于代替 “ * ”,类似 “ _ ” 的存在,不难理解
预定义的Cron时间表
输入 | 简述 | 相当于 |
@yearly (or @annually) | 1月1日午夜运行一次 | 0 0 0 1 1 * |
@monthly | 每个月的午夜,每个月的第一个月运行一次 | 0 0 0 1 |
@weekly | 每周一次,周日午夜运行一次 | 0 0 0 0 |
@daily (or @midnight) | 每天午夜运行一次 | 0 0 0 * |
@hourly | 每小时运行一次 | 0 0 |
安装
go get github.com/robfig/cron/v3@v3.0.0
编写硬删除的代码
打开 models 目录下的 tag.go、article.go文件,分别添加以下代码
- tag.go
func CleanAllTag() bool {
db.Unscoped().Where("deleted_at != ?", 0).Delete(&Tag{})
return true
}
- article.go
func ClearAllArticle() bool {
db.Unscoped().Where("deleted_at != ?", 0).Delete(&Article{})
return true
}
注意硬删除要使用 Unscoped(),这是 GORM 的约定
编写Cron
在 项目根目录下新建 cron.go 文件,用于编写定时任务的代码,写入文件内容
package main
import (
"fmt"
"gin_log/models"
"github.com/robfig/cron/v3"
"log"
"time"
)
func main() {
log.Println("Staring...")
c := cron.New()
e1, err := c.AddFunc("* * * * *", func() {
log.Println("Run models.CleanAllTag")
models.CleanAllTag()
})
if err != nil {
c.Stop()
fmt.Println(e1, err)
}
e2, err := c.AddFunc("* * * * *", func() {
log.Println("Run models.CleanAllArticle")
models.CleanAllArticle()
})
if err != nil {
c.Stop()
fmt.Println(e2, err)
}
c.Start()
timer := time.NewTicker(time.Second * 10)
for {
select {
case <-timer.C:
timer.Reset(time.Second * 10)
}
}
}
开启我们的定时任务:go run cron.go
2022/09/13 14:08:00 Run models.CleanAllArticle
2022/09/13 14:08:00 Run models.CleanAllTag
2022/09/13 14:09:00 Run models.CleanAllArticle
2022/09/13 14:09:00 Run models.CleanAllTag
这两个任务就会每分钟执行一次。
检查输出日志正常,模拟已软删除的数据,定时任务工作OK
小结
定时任务很常见,本文能够熟知golang怎么实现一个简单的定时任务调度管理。
可以不依赖系统的crontab设置。