在不同的服务器上多次停止 运行 作业的 HangFire?

Stop HangFire from running a job multiple times on different servers?

我设置了一个只处理一些订单的循环作业:

                    {
                        RecurringJob.AddOrUpdate(
                            hangFireJob.JobId,
                            () => hangFireJob.Execute(),
                            hangFireJob.Schedule);
                    }

我 运行 遇到的问题是,我们有多个“备份”服务器,所有 运行 都是相同的代码。他们都在访问同一个 HangFire 数据库。

我多次看到相同的工作 运行,这显然给我们带来了错误,因为订单已经处理。

我希望备份服务器识别出重复作业已经排队并且不再排队。我认为这样做会脱离工作名称(上面的第一个参数)。我在这里错过了什么?

我在下面包含了 hangfire 服务器设置:

        private IEnumerable<IDisposable> GetHangfireServers()
        {
            var configSettings = new Settings();
            GlobalConfiguration.Configuration
                               .UseNinjectActivator(_kernel)
                               .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                               .UseSimpleAssemblyNameTypeSerializer()
                               .UseRecommendedSerializerSettings()
                               .UseSqlServerStorage(configSettings.HangfireConnectionString, new SqlServerStorageOptions
                               {
                                   CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
                                   SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
                                   QueuePollInterval = TimeSpan.Zero,
                                   UseRecommendedIsolationLevel = true,
                                   DisableGlobalLocks = false,
                                   SchemaName = "LuxAdapter",
                                   PrepareSchemaIfNecessary = false
                               });

            yield return new BackgroundJobServer();
        }```

不确定您是否已经尝试过此操作,但考虑在作业上使用 DisableConcurrentExecution 属性以防止同一作业的多次执行。

由于默认值仅在进程级别提供唯一性,因此如果您想 运行 同一进程内的不同服务器实例,您应该手动处理它:

var options = new BackgroundJobServerOptions
{
    ServerName = String.Format(
    "{0}.{1}",
    Environment.MachineName,
    Guid.NewGuid().ToString())
};

var server = new BackgroundJobServer(options);
// or
app.UseHangfireServer(options);