libi / dcron

轻量分布式定时任务库 a lightweight distributed job scheduler library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

如何保证一个任务在同一个周期内只执行一次?

ZAKLLL opened this issue · comments

commented
为什么不直接用分布式锁实现?
通过各个节点在定时任务内抢锁方式实现,需要依赖各个节点系统时间完全一致,当系统时间有误差时可能会导致以下问题:

如果任务的执行时间小于系统时间差,任务仍然会被重复执行(某个节点定时执行完毕释放锁,又被另一个因为系统时间之后到达定时时间的节点取得锁)。
即使有极小的误差,因为某个节点的时间会比其他节点靠前,在抢锁时能第一时间取得锁,所以导致的结果是所有任务都只会被该节点执行,无法均匀分布到多节点。

dcron 是如何解决这个问题的呢,我看核心代码:
通过一致性hash 获取到的节点为当前节点的话即进行执行,好像也会出现时间误差的情况吧

//Run is run job
func (job JobWarpper) Run() {
	//如果该任务分配给了这个节点 则允许执行
	if job.Dcron.allowThisNodeRun(job.Name) {
		if job.Func != nil {
			job.Func()
		}
		if job.Job != nil {
			job.Job.Run()
		}
	}
}
commented

so sry,我理解了这个设计了,不同节点 在到达执行时间点的时候通过hash拿到的节点,如果不是自己,不进行执行,功能等效于抢锁的操作,又因为每个任务一般只在同一个节点上执行,所以保证了一个任务周期内只会执行一次