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 * * * * |