goCron是一个go程序调度包,通过简单的语法即可让程序在按照指定时间间隔运行。
简介
源码地址
https://github.com/jasonlvhit/gocron
使用场景
- 单机定时任务
- 分布式定时任务
使用demo
package main
import (
"fmt"
"time"
"github.com/jasonlvhit/gocron"
)
func task() {
fmt.Println("I am running task.")
}
func taskWithParams(a int, b string) {
fmt.Println(a, b)
}
func main() {
// Do jobs without params
gocron.Every(1).Second().Do(task)
gocron.Every(2).Seconds().Do(task)
gocron.Every(1).Minute().Do(task)
gocron.Every(2).Minutes().Do(task)
gocron.Every(1).Hour().Do(task)
gocron.Every(2).Hours().Do(task)
gocron.Every(1).Day().Do(task)
gocron.Every(2).Days().Do(task)
gocron.Every(1).Week().Do(task)
gocron.Every(2).Weeks().Do(task)
// Do jobs with params
gocron.Every(1).Second().Do(taskWithParams, 1, "hello")
// Do jobs on specific weekday
gocron.Every(1).Monday().Do(task)
gocron.Every(1).Thursday().Do(task)
// Do a job at a specific time - 'hour:min:sec' - seconds optional
gocron.Every(1).Day().At("10:30").Do(task)
gocron.Every(1).Monday().At("18:30").Do(task)
gocron.Every(1).Tuesday().At("18:30:59").Do(task)
// Begin job immediately upon start
gocron.Every(1).Hour().From(gocron.NextTick()).Do(task)
// Begin job at a specific date/time
t := time.Date(2019, time.November, 10, 15, 0, 0, 0, time.Local)
gocron.Every(1).Hour().From(&t).Do(task)
// NextRun gets the next running time
_, time := gocron.NextRun()
fmt.Println(time)
// Remove a specific job
gocron.Remove(task)
// Clear all scheduled jobs
gocron.Clear()
// Start all the pending jobs
<- gocron.Start()
// also, you can create a new scheduler
// to run two schedulers concurrently
s := gocron.NewScheduler()
s.Every(3).Seconds().Do(task)
<- s.Start()
}
代码阅读
主要包含两个结构体Scheduler和Job. Job为需要执行的任务,详细结构如下:
Job
// Job struct keeping information about job
type Job struct {
interval uint64 // pause interval * unit between runs
jobFunc string // the job jobFunc to run, func[jobFunc]
unit timeUnit // time units, ,e.g. 'minutes', 'hours'...
atTime time.Duration // optional time at which this job runs
err error // error related to job
loc *time.Location // optional timezone that the atTime is in
lastRun time.Time // datetime of last run
nextRun time.Time // datetime of next run
startDay time.Weekday // Specific day of the week to start on
funcs map[string]interface{} // Map for the function task store
fparams map[string][]interface{} // Map for function and params of function
lock bool // lock the job from running at same time form multiple instances
tags []string // allow the user to tag jobs with certain labels
}
参数解释:
- interval、unit: 两个参数共同决定了job两次执行的时间间隔interval*unit
- jobFunc: job函数名称
- atTime: job第一次运行时刻, 需要注意的是只有unit为days、weeks才生效, unit为seconds、minustes、hours时可以使用From方法设置nextRun来设置第一次运行时间.
- loc: 时区
- lastRun: 上次Job执行日期
- nextRun: 下次Job执行日期
- startDay: unit为days时生效, 周几开始执行Job
- funcs: 存储执行函数
- fparams: 执行函数所需要的参数
- lock: 相同任务不允许同时执行时设置lock=true, 包含单机和分布式, 分布式时使用分布式锁即可
- tags: 给任务添加标签
Scheduler
// Scheduler struct, the only data member is the list of jobs.
// - implements the sort.Interface{} for sorting jobs, by the time nextRun
type Scheduler struct {
jobs [MAXJOBNUM]*Job // Array store jobs
size int // Size of jobs which jobs holding.
loc *time.Location // Location to use when scheduling jobs with specified times
}
参数解释:
- jobs: 存储Job的数组
- size: 存储的Job个数
- loc: 时区
方法介绍:
- NewScheduler: 创建调度器
- Start: 开启调度器
调度策略
调用start后, scheduler启动一个goroutine, goroutine中开启一个秒级别定时器, 每秒钟遍历检查一次jobs, 选择出可以执行的job之后,对每个需要执行的job各自开辟新的goroutine执行. 选择job方法为:
- 按照job的nextRun排序
- 遍历排序后的jobs数组