Go使用Cron开启定时任务

本文重点

Gin结合Cron实现定时任务

需要导入的包

go get "github.com/robfig/cron/v3"

简单介绍


// run the scheduler.. this is private just due to the need to synchronize
// access to the 'running' state variable.
func (c *Cron) run() {
	c.logger.Info("start")

	// Figure out the next activation times for each entry.
	now := c.now()
	for _, entry := range c.entries {
		entry.Next = entry.Schedule.Next(now)
		c.logger.Info("schedule", "now", now, "entry", entry.ID, "next", entry.Next)
	}

	for {
		// Determine the next entry to run.
		sort.Sort(byTime(c.entries))

		var timer *time.Timer
		if len(c.entries) == 0 || c.entries[0].Next.IsZero() {
			// If there are no entries yet, just sleep - it still handles new entries
			// and stop requests.
			timer = time.NewTimer(100000 * time.Hour)
		} else {
			timer = time.NewTimer(c.entries[0].Next.Sub(now))
		}

		for {
			select {
			case now = <-timer.C:
				now = now.In(c.location)
				c.logger.Info("wake", "now", now)

				// Run every entry whose next time was less than now
				for _, e := range c.entries {
					if e.Next.After(now) || e.Next.IsZero() {
						break
					}
					c.startJob(e.WrappedJob)
					e.Prev = e.Next
					e.Next = e.Schedule.Next(now)
					c.logger.Info("run", "now", now, "entry", e.ID, "next", e.Next)
				}

			case newEntry := <-c.add:
				timer.Stop()
				now = c.now()
				newEntry.Next = newEntry.Schedule.Next(now)
				c.entries = append(c.entries, newEntry)
				c.logger.Info("added", "now", now, "entry", newEntry.ID, "next", newEntry.Next)

			case replyChan := <-c.snapshot:
				replyChan <- c.entrySnapshot()
				continue

			case <-c.stop:
				timer.Stop()
				c.logger.Info("stop")
				return

			case id := <-c.remove:
				timer.Stop()
				now = c.now()
				c.removeEntry(id)
				c.logger.Info("removed", "entry", id)
			}

			break
		}
	}
}

         大致看一下源码,实际上也是通过定时器time.NewTimer()来开启定时任务。只不过是封装了一下,很方便,开箱即用。

简单用法

        

// 先实例化一下
c:=cron.New()
// 每五秒执行一次
c.AddFunc("@every 5s", func() { 
fmt.Printf("Every five seconds, %s\n", time.Now().Format("15:04:05")) 
})
c.Start()

官方文档

官方链接附上....

实战

封装的定时方法,开启的一个子协程并利用读写锁去操作Map


func DeviceWaitChannel() {
	newTime := time.Now().Unix()
	//子协程
	go func() {
		lock.RLock()
		defer lock.RUnlock()
		for key, value := range deviceMap {
			if newTime-value.StartTime > 100 {
				println(newTime)
				deviceMap[key] = entity.DeviceIpValue{Status: result.CodeFailed}
			}
		}
	}()
	time.Sleep(time.Second * 2)
}

 本来打算使用time.ticker()来做定时任务,后来试过许多方法发现无法在主协程里面去跑,所以采用Gin+Cron来解决定时任务

启动类写法


func main() {
	deviceCron := cron.New()
	//每5秒执行一次
	_, err2 := deviceCron.AddFunc("@every 5s", func() {
		service.DeviceWaitChannel()
	})
	if err2 != nil {
		return
	}
	deviceCron.Start()
	r := gin.New()
	r = route.PathRoute(r)

	err := r.Run(":8082")
	if err != nil {
		return
	} //监听并在127.0.0.1:8888 上启动服务
}

启动类这块应该有更好的写法....不过暂时能用,后期再CR一下

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值