我正在使用最新的稳定篝火(1.6.17.0)。
我有4-6名工人在任何时候并行运行。
当新员工启动时,他们正在验证是否已创建好所有作业 - 并使用以下代码添加/更新应运行的所有作业:
var jobId = HangfireConsts.FormatReccurringJobStore(storeId);
RecurringJob.AddOrUpdate(
jobId,
() => ExecuteRefreshStore(storeId),
Cron.HourInterval(8),
null,
HangfireConsts.QueueStores);
我认为这应该是无害的,因为我使用的是AddOrUpdate() - 所以最糟糕的情况是它应该只更新现有的。锁定系统将确保每个作业都添加一次(基于jobId)。这使得我甚至可以为调度程序启动一个全新的干净模式,并获得持久的结果 - 因为所有重复的作业都将被重新创建。
然而,我可以看到一些工作开始,完全相同的jobId,在多个工人的同一时间被触发。有时在2名工人上并行,有时在3名工人上并行,有时在4或5名(6名)。
怎么可能?这是一个错误吗?
答案 0 :(得分:1)
以下内容基于Performing recurrent tasks文档的评论:
一种方法是不创建预定作业,而是创建单次延迟作业,在完成处理时创建新的延迟作业。
这个问题的主要问题是,如果你启动两个处理器,你现在必须决定他们中的哪一个安排第一份工作。
另一种方法是在作业方法上使用[DisableConcurrentExecution]
属性和0超时以及AutomaticRetry
来避免重试(并警告日志):
[DisableConcurrentExecution(0)]
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
答案 1 :(得分:0)
嘿,我们遇到了同样的问题,发现有人对我们的Cron表达式进行了更改,试图添加次分钟的问题,这对我们造成了上述问题。
坏:
public static CronExpression Minutely()
{
return new CronExpression("* * * * * *");
}
public static CronExpression Hourly(int minute)
{
return new CronExpression($"* {minute} * * * *");
}
好:
public static CronExpression Minutely()
{
return new CronExpression("* * * * *");
}
public static CronExpression Hourly(int minute)
{
return new CronExpression($"{minute} * * * *");
}