避免 hangfire 作业重复的技巧?

Tips to avoid hangfire jobs to duplicate?

我遇到一个问题,hangfire 上的某些作业使用相同的参数排队不止一次,这些作业几乎同时排队。

我尝试将 worker 的数量限制为一个,然后用 DisableConcurrentExecution 修饰我的方法。

我正在使用 sqlserver 作为存储。有没有人遇到过这个问题,有一些技巧可以避免吗?

PS:我使用 DisableConcurrentExecution 因为 hangfire 文档说互斥锁和信号量不能保证只调用一次作业。

PS2:检查我的 hangfire 服务器我注意到我有两个实例,每个实例有 1 个工作人员,所以我认为这是一个并行问题而不是并发问题。

根据 Hangfire documentation,当重复出现的 jobs/tasks 没有标识符时会出现重复作业问题:"Use unique identifiers for each recurring job, otherwise you’ll end with a single job.".

RecurringJob.AddOrUpdate("some-id", () => Console.WriteLine(), Cron.Hourly);

来源:

  1. https://gist.github.com/odinserj/a8332a3f486773baa009;
  2. https://discuss.hangfire.io/t/how-do-i-prevent-creation-of-duplicate-jobs/1222/4;

这项工作适合我。我用了MaximumConcurrentExecutions(1)装饰hangfire运行的接口方法

这并不能单独解决我的问题,因为有多个服务器(自动扩展)。

所以在启动时 class 我创建了另一个 backgroundjobserveroptions 来为这个作业创建一个独占服务器,以保证当应用程序扩展时这不会创建另一个带有另一个队列的服务器,我不得不查询sqlserver hangfire.server 并检查我的队列是否已经存在。

if(!HangfireServerInfo.QueueExists("queuename", AppSettings.GetConnectionString("Hangfire"))){
        var hangfireServerOptions = new BackgroundJobServerOptions { WorkerCount = 1, Queues = new[] {"queuename"} };
        app.UseHangfireServer(hangfireServerOptions);
    }


public static class HangfireServerInfo
    {
        public static bool QueueExists(string queueName, string connectionString)
        {
            using (var connection = new SqlConnection(connectionString))
            {
                var cmd = connection.CreateCommand();
                cmd.CommandText = 
                    $@"SELECT COUNT(*) 
                    FROM {YOURHANGFIRESERVER.server}
                    WHERE JSON_QUERY(data, '$.queues') = '[""{queueName}""]'";

                connection.Open();
                var result = (int)cmd.ExecuteScalar();
                connection.Close();

                return result > 0;
            }
        }
    }

可能这是解决问题的更好方法,但这行得通。