go任务调度---Cronexpr 包

获取包

go get -u github.com/gorhill/cronexpr
  • Parse():解析与校验Cron表达式
  • Next():根据当前时间,计算下次调度时间
调度单个cron
package main

import (
	"fmt"
	"time"
	"github.com/gorhill/cronexpr"
)



func main() {
	var (
		expr *cronexpr.Expression
		err error
		now time.Time
		nextTime time.Time
	)
	// 每隔五 秒执行一次,(这个库支持 7 位,精确到秒、分、时、日、月、周、年)
	if expr, err = cronexpr.Parse("*/5 * * * * * *"); err !=nil {
		fmt.Println(err)
		return
	}
	// 当前时间
	now = time.Now()
	// 下次调度时间
	nextTime = expr.Next(now)
	// 等待这个定时器超时
	time.AfterFunc(nextTime.Sub(now), func() {
		fmt.Println("被调度了:", nextTime)
	}) // 下次时间减去当前时间
	time.Sleep(10 * time.Second)
}


/// 执行结果
被调度了: 2019-05-20 15:05:25 +0800 CST

调度多个cron任务
package main

import (
	"fmt"
	"time"
	"github.com/gorhill/cronexpr"
)



// 调度多个cron 任务

// 定义任务结果体
type CronJob struct {
	expr *cronexpr.Expression
	nextTime time.Time
}

func main() {
	// 需要一个 协程调度,定时检查所有Cron 任务,谁过期就执行谁
	var (
		cronJob *CronJob
		expr *cronexpr.Expression
		now time.Time
		scheduleTable map[string] *CronJob //key:任务名字
	)

	scheduleTable = make(map[string]*CronJob)

	// 当前时间
	now = time.Now()

	// 定义第一个Cronjob
	expr = cronexpr.MustParse("*/5 * * * * * *")
	cronJob = &CronJob{
		expr: expr,
		nextTime: expr.Next(now),
	}

	// 任务注册到调度表
	scheduleTable["job1"] = cronJob 

	// 定义第二个cronjob
	expr = cronexpr.MustParse("*/8 * * * * * *")
	cronJob = &CronJob{
		expr : expr,
		nextTime: expr.Next(now),
	}
	// 任务注册到调度表
	scheduleTable["job2"] = cronJob 

	// 启动调度协程
	go func() {
		var (
			jobName string
			cronJob *CronJob
			now time.Time
		)

		// 定时检查任务调度表是否有到期的
		for {
			now = time.Now()
			// 循环调度任务列表
			for jobName, cronJob = range scheduleTable {
				// 判断是否过期(如果下次调度时间等于当前时间,说明已经过期了)
				if cronJob.nextTime.Before(now) || cronJob.nextTime.Equal(now) {
					// 启动一个协程,执行这个任务
					go func(jobName string) {
						fmt.Println("执行:", jobName)
					}(jobName)
					// 计算下一次调度时间
					cronJob.nextTime = cronJob.expr.Next(now)
					fmt.Println(jobName, "下次执行时间:", cronJob.nextTime)
				}
			}
			// 睡眠100 毫秒(不让它占用过多cpu)
			select {
				case <- time.NewTimer(100 * time.Millisecond).C: //将在100 毫秒可读,返回
			}
		}
	}()
	time.Sleep(100 *time.Second)

}



/// 执行结果
执行: job1
job1 下次执行时间: 2019-05-20 15:46:00 +0800 CST
job2 下次执行时间: 2019-05-20 15:46:00 +0800 CST
执行: job2
执行: job1
job1 下次执行时间: 2019-05-20 15:46:05 +0800 CST
job2 下次执行时间: 2019-05-20 15:46:08 +0800 CST
执行: job2
job1 下次执行时间: 2019-05-20 15:46:10 +0800 CST
执行: job1
job2 下次执行时间: 2019-05-20 15:46:16 +0800 CST
执行: job2

更多精彩内容