go定时任务实战

cron 表达式的基本格式

    对于cron我们比较熟知的应该是linux的crontab,但是正常来说linux中的cron 只能支持分钟级别的定时任务。而在实际运用中,我们经常需要使用到秒级别的任务,比如监控什么的。除了支持的粒度,cron 的表达式跟linux的cron基本语法是类似的。下面会介绍go 中常用到的两个cron 包的使用。

Golang 定时任务 github/robfig/cron/v3 的介绍与使用

demo实例

引用项目需要的依赖增加到go.mod文件

go mod init go_cron

代码

package main
import ( "fmt" "time"
"github.com/robfig/cron/v3")
func main() { //New(): 实例化一个 cron 对象 job := cron.New( cron.WithSeconds(), // 添加秒级别支持,默认支持最小粒度为分钟 ) i, j := 1, 1 //Cron.AddFunc()向 Cron 对象中添加一个作业,接受两个参数,第一个是 cron 表达式,第二个是一个无参无返回值的函数(作业) // 每秒钟执行一次 job.AddFunc("* * * * * *", func() { fmt.Printf("secondly: %v,times: %d\n", time.Now(), i) i++ }) //每分钟执行一次 job.AddFunc("0 * * * * *", func() { fmt.Printf("minutely: %v,times: %d\n", time.Now(), j) j++ })
job.Run() // 启动 if i >= 35 { //Cron.Stop(): 停止调度,Stop 之后不会再有未执行的作业被唤醒,但已经开始执行的作业不会受影响 job.Stop() }}

ron 默认支持到分钟级别,如果需要支持到秒级别,在初始化 cron 时,记得 cron.WithSeconds() 参数。

自动的包管理,有引用到的会自动下载,没有的会自动清理

go mod tidy  

每小时执行一次

// 每小时执行一次job.AddFunc("0 0 * * * *", func() {    fmt.Printf("hourly: %v\n", time.Now())})// 另一种写法job.AddFunc("@hourly", func() {    fmt.Printf("hourly: %v\n", time.Now())})

cron 提供的解析器,可以识别 @hourly 这种写法,类似的还有 dailyweeklymonthlyyearlyannually

固定时间间隔执行一次

cron 表达式无法直接实现,可以使用另外的方案

@every 写法

package main
import ( "fmt" "time"
"github.com/robfig/cron/v3")
func main() { //New(): 实例化一个 cron 对象 job := cron.New( cron.WithSeconds(), // 添加秒级别支持,默认支持最小粒度为分钟 ) i, j := 1, 1 //Cron.AddFunc()向 Cron 对象中添加一个作业,接受两个参数,第一个是 cron 表达式,第二个是一个无参无返回值的函数(作业) // 每秒钟执行一次 job.AddFunc("* * * * * *", func() { fmt.Printf("secondly: %v,times: %d\n", time.Now(), i) i++ }) job.AddFunc("@every 5s", func() { fmt.Printf("every: %v,times: %d\n", time.Now(), j) j++ }) job.Run() // 启动 // if i >= 35 { // //Cron.Stop(): 停止调度,Stop 之后不会再有未执行的作业被唤醒,但已经开始执行的作业不会受影响 // job.Stop() // }}

@every 也是解析器提供的功能,60s 这个写法,其实就是一个时间区间,类似的还有 1h1h30m 等,具体的格式可以通过 time.ParseDuration 获取。

执行效果

secondly: 2022-10-25 13:31:48.002104 +0800 CST m=+0.331528064,times: 1secondly: 2022-10-25 13:31:49.000388 +0800 CST m=+1.329810626,times: 2secondly: 2022-10-25 13:31:50.003159 +0800 CST m=+2.332579760,times: 3secondly: 2022-10-25 13:31:51.003097 +0800 CST m=+3.332515820,times: 4secondly: 2022-10-25 13:31:52.00265 +0800 CST m=+4.332067570,times: 5every: 2022-10-25 13:31:52.002645 +0800 CST m=+4.332062298,times: 1secondly: 2022-10-25 13:31:53.003482 +0800 CST m=+5.332897647,times: 6secondly: 2022-10-25 13:31:54.001821 +0800 CST m=+6.331234706,times: 7secondly: 2022-10-25 13:31:55.002277 +0800 CST m=+7.331689662,times: 8secondly: 2022-10-25 13:31:56.004013 +0800 CST m=+8.333424027,times: 9every: 2022-10-25 13:31:57.001743 +0800 CST m=+9.331152834,times: 2secondly: 2022-10-25 13:31:57.001756 +0800 CST m=+9.331165066,times: 10


github.com/jasonlvhit/gocron

goCron是一个Golang作业调度工具,可以使用简单的语法定期执行go函数,相比cron 的工具,gocron支持执行带参数的函数调用

实例:

每四秒钟跑一次

package main
import ( "log"
"github.com/jasonlvhit/gocron")
func main() { i := 0 s := gocron.NewScheduler() s.Every(4).Seconds().Do(func() { i++ log.Println("execute per 4 seconds", i) }) <-s.Start() // sc := s.Start()}



相比上面的cron,gocron的接口命名与使用有比较好的可读性

使用的基本用法

package main
import ( "fmt"
"github.com/jasonlvhit/gocron")
func task() { fmt.Println("I am runnning task.")}
func taskWithParams(a int, b string) { fmt.Println(a, b)}
func main() { //可併發運行多個任務 //注意 interval>1時調用sAPi gocron.Every(2).Seconds().Do(task) gocron.Every(1).Second().Do(taskWithParams, 1, "hi") //在cron所有操作最後調用 start函數,否則start之後調用的操作無效不執行 //<-gocron.Start()
//在task執行過程中 禁止異常退出 gocron.Every(1).Minute().DoSafely(taskWithParams, 1, "hello")
// 支持在具體某一天、某天的某一時刻、每y-M-d h-m-s 執行任務 gocron.Every(1).Monday().Do(task) gocron.Every(1).Thursday().Do(task) // function At() take a string like 'hour:min' gocron.Every(1).Day().At("10:30").Do(task) gocron.Every(1).Monday().At("18:30").Do(task)
// 刪除某一任務 // remove, clear and next_run _, time := gocron.NextRun() fmt.Println(time) gocron.Remove(task)
//刪除所有任務 gocron.Clear()
//可同時創建一個新的任務調度 2個schedulers 同時執行 s := gocron.NewScheduler() s.Every(3).Seconds().Do(task) <-s.Start()

// <-gocron.Start()}




请使用浏览器的分享功能分享到微信等