Go开源宝藏 go-cron 定时任务

Posted 小生凡一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go开源宝藏 go-cron 定时任务相关的知识,希望对你有一定的参考价值。

1. cron是什么

1.1 cron简介

cron:计划任务,其实就是定时任务
和系统约个时间,在几点几分几秒或者每隔一段时间跑一个任务(job),就那么简单。

1.2 cron详细语法

  • 结构

以下的结构来自维基百科

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │                                   7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

cron是一个字符串,一般分为几个域。字符串以56个空格隔开,分为67个域,每一个域代表一个含义,cron表达式有如下两种语法格式。

       秒     分钟    小时    日期      月份    星期    
1、Seconds Minutes Hours DayofMonth Month DayofWeek

      秒     分钟   小时    日期      月份    星期      年                                        
2、Seconds Minutes Hours DayofMonth Month DayofWeek Year
分钟小时日期月份星期年 (可选)
取值0 - 590 - 590 - 231 - 311 - 121 - 71970 - 2099
允许特殊字符, - * /, - * /, - * /, - * / ? L W C, - * /, - * / ? L C #, - * /
字符含义
?只能用在 DayofMonth 和 DayofWeek 两个域中,表示未说明的值,即不关心它为何值,用于解决DayofMonth 和 DayofWeek之间的冲突。因为DayofMonth 和 DayofWeek 会相互影响。例如cron表达式为* * * 20 * ?,则表示任务设置在每月的20日触发调度,不管20日到底是星期几都会触发,而如果把换成*,则表示不管星期几都会触发调度, 而DayofMonth又设置为20,表示只能在每个月的20日触发调度,这样就会引起冲突,所以必须要对其中一个设置? 来表示并不关心它为何值。
L表示last,只能出现在DayofMonth 和 DayofWeek域,例如:① 在DayofMonth域中使用L,则表示在当前月的最后一天触发一次。 ② 在DayofWeek域中使用L,则表示在当前月每周的星期六触发一次。
W只能用在月份中,表示最接近指定天的工作日 (周一到周五)。① 在DayofMonth域中使用5W 指 “最接近当前月第5天的工作日”。② 如果当前月的第5天是星期六,则将在最近的工作日:星期五,即当前月的第4天触发。③ 如果当前月的第5天是星期天,则在当前月的第6天(周一)触发;④如果当前月的第5天在星期一 到星期五之间,则就在当前月的第5天触发。⑤ W在寻找最近工作日是不会跨过月份。
  • 每分钟执行

*:表示匹配该域的任意值,假如在minute域中使用*,即表示每分钟都会触发事件。

* * * * *
  • 隔几分钟执行

一个 / 就能简单的表达了隔的意思,

*/3 * * * *
  • 从…到…
10-20 * * * * 每小时的 10-20 分执行

10-20/3 * * * * 在10-20 分钟这段时间,每3分钟执行一次
  • 指定时间段,可以用,来表示做某项任务,比如在2,4,6,19这几个时间段做任务。
2,4,6,19 * * * *
0 15 10 15 * ?  每月15日上午10:15触发 

0 15 10 ? * MON-FRI  周一至周五的上午10:15触发 

0 0 12 ? * WED   表示每个星期三中午12点 

2. 下载

github.com/robfig/cron

3. 使用

  • 导入
import "github.com/robfig/cron"
  • 创建
var Cron *cron.Cron
  • 执行
//每3秒执行一次
err := Cron.AddFunc("*/3 * * * * *", printHello)
func printHello() {
	fmt.Println("hello")
}
  • 启动一个定时器
	Cron.Start()

查看Start()源码可知,他是启动了一个协程的

所以我们加上了一个select进行阻塞。

	select {}

package main

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

var Cron *cron.Cron

func main() {
	if Cron == nil {
		Cron = cron.New()
	}

	//每3秒执行一次
	err := Cron.AddFunc("*/3 * * * * *", printHello)
	if err != nil {
		fmt.Println("err",err)
	}
	Cron.Start()
	println("created cron job")
	select {}
}

func printHello() {
	fmt.Println("hello")
}
  • 我们实际生产环境中的主进程是不会轻易结束的,所以在生产环境中不需要担心主进程的结束,而导致子进程结束的问题。

以上是关于Go开源宝藏 go-cron 定时任务的主要内容,如果未能解决你的问题,请参考以下文章

Go开源宝藏Go 语言操作 Redis

Go开源宝藏Go-Swagger 自动生成 api 接口文档

Go开源宝藏Go-Doc 自动生成项目结构目录

Go开源宝藏Golang 爬虫 | 整点新花样

Go开源宝藏JWT-Go 鉴权 | 中间件 (文末送书嗷~)

Go开源宝藏Web框架 GIN 专场 (含思维导图) | 持续更新