golang 实现定时任务 cron

1. 安装cron

go get -u github.com/robfig/cron

2. 先看一个例子

这个例子将会每秒钟打印 一次hello world

package main

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

func main (){
	c := cron.New()
	_ = c.AddFunc("* * * * * *", func() {
		fmt.Println("hello world")
	})
	c.Start()
	time.Sleep(10 * time.Second)
}

做几点说明:

  • cron.New() 创建一个cron对象
  • cron对象通过AddFunc方法将一个函数按指定的时间计划执行
  • * * * * * *就是我们的时间计划,这是指每秒执行一次,后面在详细讲
  • Start() 方法开始执行
  • time.Sleep(10 * time.Second) 防止主goroutine退出否则这个程序就会结束,任务将会无法执行

3. 解决你的疑惑

time.Sleep() 真的好吗?

我们知道这一个语句的作用是让主goroutine等待,对于一个定时任务来说主goroutine应该一直等待,time.Sleep()肯定不是最好的解决方法,那我们该怎么做呢

  • 勇敢的尝试 死循环

    注意一些IDE会提示死循环的错误,但其实是可以编译运行的

    package main
    
    import (
    	"fmt"
    	"github.com/robfig/cron"
    )
    
    func main (){
    	c := cron.New()
    	_ = c.AddFunc("* * * * * *", func() {
    		fmt.Println("hello world")
    	})
    	c.Start()
    	for {
    	}
    }
    

    这视乎达到了我们的效果,但是大家都明白这样做的后果,看下你的电脑cpu利用率,我的电脑cpu占用率是30%左右

  • 利用select改进我们的代码

    package main
    
    import (
    	"fmt"
    	"github.com/robfig/cron"
    )
    
    func main (){
    	c := cron.New()
    	_ = c.AddFunc("* * * * * *", func() {
    		fmt.Println("hello world")
    	})
    	c.Start()
    	select {
    	}
    }
    

    现在我的电脑cpu占用率是10%左右

    但这是真的是最好的版本吗?

  • for 和 select 结合

    设置一个定时器

    利用for加select等待

    每当计时器可以取值时,重置计时器

    t := time.NewTimer(time.Second * 10)
    	for {
    		select {
    		case <-t.C:
    			t.Reset(time.Second * 10)
    		}
    	}
    

* * * * * * 是什么?

这上面的例子中我们用* * * * * *来表示我们的定时计划,我已经告诉你们了,这表示每秒中执行一次,下面让我们详细的了解一下它的语法吧。

  • 这个字符串一共由6位组成,每一位之间用一个空格隔开,每一位的意思如下

    第一位:秒

    第二位:分

    第三位:时

    第四位:一月中的某天(日)

    第五位:月

    第六位:星期几

  • 我们明白了位置的含义,那么这些符号又是什么意思呢

    符号 表示的含义
    * 表示的意思,比如在第一位就表示每秒
    / 后跟数字表示每隔的意思,比如在第一位*/10,表示每隔10秒执行一次;1-30/10,表示从第一秒到第30秒每个10秒执行一次
    , 枚举,比如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行
    - 表示范围,比如第一位1-30表示第一秒到第30秒每秒执行一次
    ? 只用于 第四位 和 第六位,表示不指定值,可以用于代替 *
    具体的数字 表示具体的时刻,比如第一位是5表示第5秒执行

4. 一些常用表达式举例

含义 表达式
每隔10秒执行一次 */10 * * * * *
每个10分钟执行一次 0 */10 * * * *
每天0点0时0分执行一次 0 0 0 * * *
每天9点18点执行一次 0 0 9,18 * * *

其实cron也给了一些预定义的表达式

预置表达式 描述 表达式
@yearly (or @annually) 1 月 1 日午夜运行一次 0 0 0 1 1 *
@monthly 每个月的午夜,每个月的第一个月运行一次 0 0 0 1 * *
@weekly 每周一次,周日午夜运行一次 0 0 0 * * 0
@daily (or @midnight) 每天午夜运行一次 0 0 0 * * *
@hourly 每小时运行一次 0 0 * * * *
posted @ 2020-07-18 10:44  KainHuck  阅读(1657)  评论(0编辑  收藏  举报