【问题标题】:How to ensure Hangfire jobs scheduled just once in web farm如何确保在网络场中只安排一次 Hangfire 作业
【发布时间】:2020-05-25 11:15:49
【问题描述】:

每次我部署我的应用程序时,我都会删除所有重复的作业并重新添加它们,如下所示:

JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(x => RecurringJob.RemoveIfExists(x.Id));
....
MyJobs.ForEach(x => RecurringJob.AddOrUpdate<....

我需要这样做以解决激活问题,即我在每次部署时更改程序集的版本号,并且在部署“MyAssembly,2.0.0.0”后,“MyAssembly,1.0.0.0”的原始记录不再激活正确,所以在每次发布后(实际上是每次应用程序池重启),我都会删除重复的作业并重新安排它们。一切都很好。

我正在寻找开始在网络场中运行我的作业,我希望这段代码可以删除作业并重新添加它们,以便每个“环境”发生一次,而不是每个 hangfire 服务器一次,所以几个服务器不是一遍又一遍地竞争和添加相同的工作。

我可能可以通过 web.config 设置将一个实例指定为“领导者”,并且只有领导者会执行作业调度,但如果我的“领导者”在部署后没有上线怎么办。我还希望我的所有配置文件都是相同的,而不必在我的 CD 管道中将一个配置为“领导者”。

处理这种情况的最佳方法是什么 - Hangfire 有内置的东西吗?

【问题讨论】:

  • 无论如何,计划的作业都不会在每个hangfire服务器上安排。当计划的作业开始时,它将执行kn任何服务于队列作业的hangfire服务器应该运行。不知道你从哪里得到了领导者/奴隶的概念
  • 我不是在谈论作业的运行。 IIS 重置后,我删除所有重复作业并重新添加它们(调度信息存储在我的表中)。删除作业是通过 JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(x => RecurringJob.RemoveIfExists(x.Id));然后对于我做的每一项工作 RecurringJob.AddOrUpdate ..... 理想情况下,我只想在场中的一台服务器上发生这种情况,这样服务器就不会竞争并一遍又一遍地添加相同的工作。问题已更新以反映
  • 其实任务调度应该通过Akka等框架,getakka.net使用Hangfire可能是最差的选择之一,blog.lextudio.com/unpleasant-facts-about-hangfire-632a3228ff8a
  • @LexLi 您在文章中谈到了什么样的问题?这是一篇非常省力的文章,因为它没有解释为什么 Hangfire 不好,并且建议采用一种不涵盖所有 Hangfire 使用场景的方法。

标签: asp.net jobs hangfire


【解决方案1】:

请查看Hangfire.RecurringJobCleanUpManager。它可能会为您提供如何处理重新安排重复性工作的示例。

引擎盖下没有魔法。它基本上获取所有当前的重复作业,将那些不再存在于代码中的作业删除为“已调度”(在库中:强制执行),然后添加那些在代码中但在获取当前重复作业时未出现的作业。

正如您所看到的,这与您所做的很接近,只是很好地打包成几个类。除非您想手动篡改 Hangfire 的元数据以更新程序集名称、版本等,否则没有其他方法。

在此解决方案中,我看不到与平行性相关的问题。每个服务器实例都会发生一次,但由于一个服务器实例更改了状态并使其正确,下一个服务器实例将简单地获取正确的状态并意识到它们不需要做任何事情。这将有效地使其“每个环境一次”。

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多