Go语言自定义定时器与三方cron对比

336 阅读3分钟

手动定时器写法(纯golang代码实现)

首先我们要定义一个简单的方法,在方法中new一个*Timer的实例如下代码注意看

func SetupTimer() {
	var Second1 = 1
	var Second2 = 3
	RefreshTimer1 := time.NewTimer(time.Duration(Second1) * time.Second)
	RefreshTimer2 := time.NewTimer(time.Duration(Second2) * time.Second)

	//循环监听定时器
	go func() {
		for {
			select {
			case <-RefreshTimer1.C:
				//队列缓存
				if err := NewStoreQueueService().RefreshTmpList(); err != nil {
					log.Println("RefreshTmpList:定时任务出错:", err.Error())
					return
				}

				//超时后重置定时器需要跟上面RefreshTimer1设置的时间一样
				RefreshTimer1.Reset(time.Duration(Second1) * time.Second)

			case <-RefreshTimer2.C:
				if err := NewStoreQueueService().RefreshWork(); err != nil {
					log.Println("RefreshWork:定时任务出错:", err.Error())
				}
				//超时后重置定时器 1秒执行一次
				RefreshTimer2.Reset(time.Duration(Second2) * time.Second)
			}
		}
	}()
}

上面图中我new了2个*Time 的实例为什么了·因为我们要有2个不同时间的定时器。用2个不同的case来区分2个定时器,而图中的Second1和Second2是用来做时间间隔的,也就是说多少秒钟执行一次任务·具体case里面的话·就去调用自己实例化好的方法。你也可以写成结构体对象,然后实例化结构体以后再调用结构体重点work方法。

下面是定时器具体不同case中调用的任务方法,注意看下图

package service

import (
	"log"
	"sync"
)

type StoreQueueService struct {
	sync.Mutex
}

func NewStoreQueueService() *StoreQueueService {
	return &StoreQueueService{}
}

//刷新缓存数据
func (s *StoreQueueService) RefreshTmpList() (err error) {
	s.Lock()
	defer s.Unlock()
	log.Println("处理任务方法1。。。。")
	return
}

func (s *StoreQueueService) RefreshWork() error {

	log.Println("处理任务方法2。。。。")
	return nil
}

上面这段代码就是我上面黄色字体中说到的,先定义一个结构体·然后定义个构造方法,最后给这个结构体定义一个自己的work方法。也就是,RefreshTmpList()或者RefreshWork()方法。
那么最终我们看下定时器的效果,如下图。我们定时器任务一RefreshTimer1的话是1秒执行一次。RefreshTimer2是3秒执行一次。

image.png

上面的代码,如果你单纯为了想秀一把操作,可以这么在公司写。

但是我个人感觉这么写了有点麻烦。不过我以前在公司的项目也是这么写的·
但是我最近的新项目我打算用三方定时器

三方定时器库使用

首先我们要拉取依赖

go get github.com/robfig/cron/v3

让我们要定义一个结构体,在结构体中定义自己的方法。和结构体对外暴露的构造器如下代码:

package service

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

var (
	AutoTaskService *AutoTackService
)

type AutoTackService struct {
	Task *cron.Cron
}

// NewAutoTaskService 实例化结构体,同时也实例化 corn定时器
func NewAutoTaskService() *AutoTackService {
	secondParser := cron.NewParser(cron.Second | cron.Minute |
		cron.Hour | cron.Dom | cron.Month | cron.DowOptional | cron.Descriptor)
	return &AutoTackService{
		Task: cron.New(cron.WithParser(secondParser), cron.WithChain()),
	}
}

func InitAutoTask() {
	AutoTaskService = NewAutoTaskService()
	AutoTaskService.startCron()
}

func (this *AutoTackService) startCron() {
	//这里写实例化的任务对象,然后在下面的 func回调方法中回调任务方法。

	this.Task.AddFunc("*/1 * * * * *", func() {
		fmt.Println("每1秒执行一次")
	})

	this.Task.AddFunc("*/5 * * * * *", func() {
		fmt.Println("每5秒执行一次")
	})
	this.Task.AddFunc("@hourly", func() {
		fmt.Println("每个小时执行一次")
	})
	this.Task.AddFunc("@every 1h30m", func() {
		fmt.Println("每个小时的第三十分钟执行")
	})
	//启动定时器
	this.Task.Start()
}

最后就是调用使用的地方了。

package main

import "setupTime/service"

func main() {
	//自定义定时器
	//service.SetupTimer()
	//三方定时器
	service.InitAutoTask()

	select {}
}

大家注意看startCron 方法中·这样我们就可以在同一个方法中统一管理 不同的定时器,并且每个定时器内部有一个func()回调方法,大家可以自行在该回调方法中扩展自己的对象方法。在对象方法中调用work方法来完成定时任务,是不是很优雅。是不是非常爽.最后希望大家给个点赞吧。后续在还有好多日常开发的好东西想分享给大家。

最后给大家奉上代码地址如下:

https://gitee.com/golang520/setup-time.git

最后开源不易,希望各位大佬帮忙点个小赞谢谢!!!