注意,注意,注意:看结果直接拉到最底下看(三)
一.自己网上找的资料
cron这个包是用来给一个定时任务逻辑的
网上大多数的方法如下:
一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。
func main() {
i:= 0
c:= cron.New()
spec := "*/5 * * * * ?"//注意注意,这么写不是每五秒执行,其他写法看文章最下面
c.AddFunc(spec, func() {
i++
log.Println("cron running:", i)
})
c.Start()
select{}
}
实际上,这样的写法只能实现每多少分钟执行一次,并不是每多少秒
1.这里还有一些解释:注意的是,这里大多数都是网上抄来抄去的,其实很多都是含有错误的结论,这里只是摘要了一些,中间对秒的处理其实理解的不对的。
2.想直接看结论,直接拉到最下面,看二的最后一部分解决过程
3.至于为什么会有这样的解释,因为Scheduled的这种写法是java里面也有的,java里面的资料是这么写的,估计不知道是谁先拿过来看,然后产生了恶性循环,比如说下面这些(可以去百度一下,大部分都是这么写,这里摘了一点)
按顺序依次为
秒(0~59)
分钟(0~59)
小时(0~23)
天(月)(0~31,但是你需要考虑你月的天数)
月(0~11)
天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
7.年份(1970-2099)
2、特殊字符说明
1)星号(*)
表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month),表示每个月
2)斜线(/)
表示增长间隔,如第1个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后每隔 15 分钟执行一次(即 3、18、33、48 这些时间点执行),这里也可以表示为:3/15
3)逗号(,)
用于枚举值,如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行
4)连字号(-)
表示一个范围,如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时(包括9和17)
5)问号(?)
只用于日(Day of month)和星期(Day of week),\表示不指定值,可以用于代替 *
其中每个元素可以是一个值(如6),一个连续区间(9-12),一个间隔时间(8-18/4)(/表示每隔4小时),一个列表(1,3,5),通配符。由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?.
3、cron举例说明
每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
在26分、29分、33分执行一次:0 26,29,33 * * * ?
每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
有些子表达式能包含一些范围或列表
例如:子表达式(天(星期))可以为 “MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT”
“”字符代表所有可能的值
因此,“”在子表达式(月)里表示每个月的含义,“”在子表达式(天(星期)*)表示星期的每一天
“/”字符用来指定数值的增量
例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟
在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样
“?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值
当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”
“L” 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写
但是它在两个子表达式里的含义是不同的。
在天(月)子表达式中,“L”表示一个月的最后一天
在天(星期)自表达式中,“L”表示一个星期的最后一天,也就是SAT
如果在“L”前有具体的内容,它就具有其他的含义了
例如:“6L”表示这个月的倒数第6天,“FRIL”表示这个月的最一个星期五
注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题
二。解决过程(实际看源码得出的结论,已解决)
实际输入六个参数,会有如下报错,他说最多5个
![](https://img.haomeiwen.com/i9834648/00042aa1cd498fa9.png)
出自于:parser.go文件中的normalizeFields方法中,这里约束了只有五个
![](https://img.haomeiwen.com/i9834648/653c60f7e42061ce.png)
所以网上大部分的六七个参数的实际使用是不太正确的,那怎么处理秒级的呢,还是已经没有可以处理秒的事件呢,继续看他的参数来源。
![](https://img.haomeiwen.com/i9834648/f07c7bebf40da410.png)
看到这里,我可以确定,肯定有对秒级处理的方法。这里都是四年前的处理方法,肯定有更新,继续找。
![](https://img.haomeiwen.com/i9834648/4358ce250692b6bd.png)
看到了这个方法之后,看了一下他的注解,更加坚定了自己的想法,他这里说需要五个条目,就是上面的五个参数,但是呢,最后还有一个描述符,其实确实是有六个参数的,主要让我兴奋的是,最后一句话,就是这个@符号后面这一块,而后全文搜索了一下,果然有
![](https://img.haomeiwen.com/i9834648/5f912be47504e585.png)
这里写出了所有可以配对的“每。。。”,就是每隔多少时间执行一次,中间还用时间解析出来了,看到这里我就豁然开朗了,终于知道每秒怎么处理了。不多说了,解释废话,直接上代码。
三。每五秒处理一次的函数过程:
func jobTest() {
i := 0
c := cron.New()
spec := "@every 5s"
id, err := c.AddFunc(spec, func() {
i++
log.Println("cron running:", i)
})
if err != nil {
log.Println("err:", err)
return
}
log.Println("id:", id)
c.Start()
select {}
}
实验结果
![](https://img.haomeiwen.com/i9834648/f35b39eb77ef0a3f.png)
网友评论