Fuhui

基于Go的Cron Job实现


随风要稳,逆风要浪

timer

The Timer type represents a single event. When the Timer expires, the current time will be sent on C.

下面使用timer实现在固定时间点执行task任务。

处理思路:每次在执行task前,计算当前时间执行时间点的差值,通过设置timer未来的触发时间来执行任务。在完成本次task之后,重置timer的触发时间,等待下一次执行。

const IntervalPeriod time.Duration = 24 * time.Hour

// 核心函数:在h:m:s的时候执行task任务
func runningRoutine(hour, minute, second int, task func() error) {
	ticket := time.NewTimer(GetNextTickDuration(hour, minute, second))
	for {
		<-ticket.C
		if err := task(); err != nil {
		}
		ticket.Reset(GetNextTickDuration(hour, minute, second))
	}
}

// 获取Task执行的时间
func GetNextTickDuration(hour, minute, second int) time.Duration {
	nextTick := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(),
		hour, minute, second, 0, time.Local)
	if !nextTick.After(time.Now()) {
		nextTick = nextTick.Add(IntervalPeriod)
	}

	return nextTick.Sub(time.Now())
}

ticker

ticker只要定义完成,从此刻开始计时,不需要任何其他的操作,每隔固定时间都会触发。

func simulateCronByInterval(interval time.Duration, task func()) {
	ticker := time.NewTicker(interval)
	defer func() {
		ticker.Stop()
	}()

	for {
		<-ticker.C:
			task()
	}
}

参考文章:

  1. Golang: Implementing a cron / executing tasks at a specific time