The cron tab will stop after a while.
van-scott opened this issue · comments
If two machines start the cron tab at the same time, the cron tab will stop after a while, the code is as follows
func main() {
drv, _ := dredis.NewDriver(&dredis.Conf{
Host: "10.203.169.19",
Port: 1841,
Password: "005f4ce0b221abf",
}, redis.DialConnectTimeout(time.Second*10))
dcronDemo := dcron.NewDcron("server1", drv, cron.WithSeconds())
//添加多个任务 启动多个节点时 任务会均匀分配给各个节点
dcronDemo.AddFunc("s1 test1", "0 */1 * * * *", func() {
fmt.Println("执行 service1 test1 任务", time.Now().Format("15:04:05"))
})
dcronDemo.AddFunc("s1 test2", "0 */1 * * * *", func() {
fmt.Println("执行 service1 test2 任务", time.Now().Format("15:04:05"))
})
dcronDemo.AddFunc("s1 test3", "0 */1 * * * *", func() {
fmt.Println("执行 service1 test3 任务", time.Now().Format("15:04:05"))
})
dcronDemo.Start()
//测试120分钟后退出
time.Sleep(120 * time.Minute)
}
请使用 master 分支最新版本,然后提供下运行日志。
没有报错信息
_, err := rd.do("EXPIRE", key, int(rd.timeout/time.Second))
if err != nil {
log.Printf("redis expire error %+v", err)
}
原因是redis key 的有效期时间太短,但凡rd.do()方法超过了有效期,这个key 就会消失,crontab 就会失效,建议判断rd.do()
的结果,如果延迟有效期失败即非等于1 。 就要重新注册
for range tickers.C {
ok, err := rd.do("EXPIRE", key, int(rd.timeout/time.Second))
if err != nil {
log.Printf("redis expire error %+v", err)
continue
}
if ok != 1 { //redis expire 返回1 是成功,0 是key 是不存在,
rd.ReRegisterServiceNode(key)
}
}
//ReRegisterServiceNode When the data expires, you need to re-register
func (rd *RedisDriver) ReRegisterServiceNode(nodeID string) {
_, err := rd.do("SETEX", nodeID, int(rd.timeout/time.Second), nodeID)
if err != nil {
log.Printf("re-register service node is err, message is %s ", err)
}
}
感谢建议 这里确实是有这个问题,我修复下。
现在每 n/2 设置 有效期 n,如果expire 执行时间大于 n/2 会导致 key 被释放节点失效。 但是这种情况下任务都会自动转移到另一个节点呀 你是两个节点任务都没了吗
是的,我跑一天的话,很容易两个节点的任务都没了的
好的,master 分支已经修复了