Gin实践 连载八 Cron定时任务

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特殊字符

  1. 星号(*)
    星号表示将匹配字段的所有值
  2. 斜线(/)
    斜线用户 描述范围的增量,表现为 “N-MAX/x”,first-last/x 的形式,例如 3-59/15 表示此时的第三分钟和此后的每 15 分钟,到59分钟为止。即从 N 开始,使用增量直到该特定范围结束。它不会重复
  3. 逗号(,)
    逗号用于分隔列表中的项目,例如,在 Day of week 使用“MON,WED,FRI”将意味着星期一,星期三和星期五
  4. 连字符(-)
    连字符用于定义范围。例如,9 - 17 表示从上午 9 点到下午 5 点的每个小时
  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文件,分别添加以下代码

  1. tag.go
func CleanAllTag() bool {
	db.Unscoped().Where("deleted_at != ?", 0).Delete(&Tag{})
	return true
}
  1. 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设置。

posted @ 2022-09-13 14:13  专职  阅读(1447)  评论(0编辑  收藏  举报