zoukankan      html  css  js  c++  java
  • 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 * * * *
  • 相关阅读:
    面试必备的数据库悲观锁与乐观锁
    5分钟带你读懂事务隔离性与隔离级别
    带你了解数据库中事务的ACID特性
    带你了解数据库中group by的用法
    带你了解数据库中JOIN的用法
    一篇带你读懂TCP之“滑动窗口”协议
    通过“表白”的方式,让我们快速了解网络协议
    聊一聊Iterable与Iterator的那些事!
    一篇让你明白进程与线程之间的区别与联系
    MySQL 索引的增删查
  • 原文地址:https://www.cnblogs.com/kainhuck/p/13334851.html
Copyright © 2011-2022 走看看