跳过正文
  1. 文章/
  2. GoLang/
  3. 常用包/
  4. 第三方包/

12、cron

·962 字·2 分钟· loading · loading · ·
GoLang 常用包 第三方包
GradyYoung
作者
GradyYoung
第三方包 - 点击查看当前系列文章
§ 12、cron 「 当前文章 」

cron是golang实现定时任务比较好的库, 这个库提供了一个简单而强大的接口,用于创建和管理基于cron表达式的定时任务。cron库的主要特点有:

  • 基于cron表达式的任务调度
  • 多任务支持
  • 容错和错误处理
  • 可靠性
  • 易用的API
  • 灵活性
  • 并发安全

安装
#

go get -u github.com/robfig/cron/v3@v3.0.0

简单使用
#

package main

import (
    "fmt"
    "github.com/robfig/cron/v3"
)

func main() {
    // 创建一个默认的cron对象
    c := cron.New()

    // 添加任务
    c.AddFunc("30 * * * *", func() { fmt.Println("Every hour on the half hour") })
    c.AddFunc("30 3-6,20-23 * * *", func() { fmt.Println(".. in the range 3-6am, 8-11pm") })
    c.AddFunc("@hourly",      func() { fmt.Println("Every hour, starting an hour from now") })
    c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty, starting an hour thirty from now") })
    c.Start()

    //开始执行任务
    c.Start()

    //阻塞
    select {}
}

预定的 Schedules
#

条目 描述 等效于
@yearly (or @annually) Run once a year, midnight, Jan. 1st 0 0 1 1 *
@monthly Run once a month, midnight, first of month 0 0 1 * *
@weekly Run once a week, midnight between Sat/Sun 0 0 * * 0
@daily (or @midnight) Run once a day, midnight 0 0 * * *
@hourly Run once an hour, beginning of hour 0 * * * *
@every <duration> 固定间隔执行,@every 1h30m10s 表示 1小时30分钟10秒后执行,并且之后的每个时间间隔都执行。

精确到秒的 Cron 表达式
#

Cron v3 版本的表达式从六个参数调整为五个,取消了对秒的默认支持,需要精确到秒的控制可以使用 cron.WithSeconds() 解析器。

c := cron.New(cron.WithSeconds())
c.AddFunc("*/1 * * * * *", func() {
    fmt.Println("Every 1 Second")
})
c.Start()

如果你仅仅需要每隔 N 秒运行一次 Job,可以使用 @every 这样的特殊 spec 表达式。

c := cron.New()
c.AddFunc("@every 10s", func() {
    fmt.Println("Every 10 Seconds")
})
c.Start()

时区设置
#

// 本地时区早六点
cron.New().AddFunc("0 6 * * ?", ...)

// 上海时区早六点
nyc, _ := time.LoadLocation("Asia/Shanghai")
c := cron.New(cron.WithLocation(nyc))
c.AddFunc("0 6 * * ?", ...)

// 上海时区早六点
cron.New().AddFunc("CRON_TZ=Asia/Shanghai 0 6 * * ?", ...)

// 重庆时区早六点
c := cron.New(cron.WithLocation(nyc))
c.SetLocation("Asia/Tokyo")
c.AddFunc("CRON_TZ=Asia/Chongqing 0 6 * * ?", ...)

Cron 方法
#

  • AddFunc() - 支持传入如 @every 这样的 spec 表达式和标准表达式及 func() 函数,它封装了 AddJob()
  • AddJob() - 支持传入 spec 和标准表达式及 Job,Job 是一个接口,实现 Run() 方法的类型即是一个 Job,它封装了 Schedule()
  • Schedule() - 执行标准表达式和 Job,被 AddJob() 函数调用,只支持标准 Cron 表达式。
  • Entries() - 获取全部 Entry,一个 Entry 即为一个定时任务条目。
  • Entry() - 根据 EntryID 获取指定条目。
  • Remove() - 根据 EntryID 移除指定条目。
  • Location() - 获取 Local 时区。
  • Start() - 使用新的 goroutine 启动,不会阻塞当前协程,已运行的调度器重复调用会被忽略。
  • Run() - 在当前 goroutine 启动,会阻塞当前协程,已运行的调度器重复调用会被忽略。
  • Stop() - 停止调度器,返回 Context,可根据 Context 来等待任务执行完成。

可以获取任务上次、下次运行时间。

c = cron.New()
entryId, _ := c.AddFunc("@every 15m", func() {
    fmt.Println("Every 15 Minutes")
})
entry := c.Entry(entryId)
fmt.Println(entry.Next)

Job 接口
#

除了使用无参的回调方式,cron还提供了实现job接口的方式:

type Job interface {
	Run()
}

示例如下:

package main

import (
	"fmt"
	"time"

	"github.com/robfig/cron/v3"
)

func main() {
	job := cron.New(cron.WithSeconds())

	j := &myJob{}
	job.AddJob("@every 1s", j)
	job.Start()
	select {}
}

type myJob struct {
	i int
}

func (j *myJob) Run() {
	j.i++
	fmt.Println("hello world:", j.i)
}
第三方包 - 点击查看当前系列文章
§ 12、cron 「 当前文章 」