【问题标题】:Use multiple instance of hangfire with single database将多个hangfire实例与单个数据库一起使用
【发布时间】:2017-06-29 17:16:05
【问题描述】:

是否有人使用相同 SQL DB 的多个 Hangfire 实例(在不同的应用程序中)进行配置。因此,我不想为每个 hangfire 实例创建新的 SQL 数据库,而是想与多个实例共享同一个数据库。

根据hangfire documentation here,它从 v1.5 开始受支持但是论坛讨论 herehere 显示我们仍然在使用相同 db 运行多个实例时遇到问题

更新 1
所以根据建议和documentation 我配置hangfire 使用队列

   public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
   ILoggerFactory loggerFactory)
   {
        app.UseHangfireServer(new BackgroundJobServerOptions()
        {
            Queues = new string[] { "instance1" }
        });
   }

调用方法

[Queue("instance1")]
public async Task Start(int requestID)
{

}

这就是我排队工作的方式

 _backGroundJobClient.Enqueue<IPrepareService>(x => x.Start(request.ID));

但是,当我检查 [JobQueue] 表时,新作业的队列名称为 default,因此,hangfire 将永远不会拾取该作业,因为它会拾取队列的作业。

我认为是一个错误

更新 2

又发现了一件事。我正在使用IBackgroundJobClient 的实例。该实例由 .Net Core 的内置容器自动注入。

因此,如果我使用实例将作业排入队列,那么 hangfire 会使用 default 队列名称创建新作业

 _backGroundJobClient.Enqueue<IPrepareService>(x => x.Start(request.ID));

但是,如果我使用静态方法,那么 hangfire 会使用配置的队列名称 instance1 创建新作业

  BackgroundJob.Enqueue<IPrepareService>(x => x.Start(prepareRequest.ID));

如何在 .Net Core 中配置 hangfire,以便 IBackgroundJobClient 的实例将使用配置队列名称?

【问题讨论】:

  • 您是否尝试过为不同的实例使用不同的队列名称?如果是,还有同样的问题吗?我没有尝试过,但认为对不同的实例使用不同的队列名称不应该混淆。您也可以发布您尝试过的代码吗?
  • 这样做没有问题。你有什么问题?
  • 不,我还没用过。但这就是混乱。你是说使用不同的队列名称,但hangfire文档说You aren’t required to have additional configuration to support multiple background processing servers in the same process since Hangfire 1.5, just skip the article. Server identifiers are now generated using GUIDs, so all the instance names are uniquedocs.hangfire.io/en/latest/background-processing/…
  • ..还有我没有看到的生成的 SQL 表[Server].[Id] 与任何其他表有外键关系。那么hangfire如何识别作业属于特定实例呢?
  • 我在一个数据库上运行多个实例。无需排队。

标签: hangfire


【解决方案1】:

这可以通过简单地为每个实例设置具有不同架构名称的 SQL 服务器选项来实现。

实例 1:

configuration.UseSqlServerStorage(
    configuration.GetConnectionString("Hangfire"),
    new SqlServerStorageOptions { SchemaName = "PrefixOne" }
);

实例 2:

configuration.UseSqlServerStorage(
    configuration.GetConnectionString("Hangfire"),
    new SqlServerStorageOptions { SchemaName = "PrefixTwo" }
);

两个实例都使用相同的连接字符串,并将创建所有必需表的两个实例,前缀在设置中指定。

队列用于在同一个 Hangfire 实例中拥有不同的队列。如果要使用不同的队列,则需要指定希望 IBackgroundJobClient 侦听的队列,然后在创建作业时指定该队列。这听起来不像你想要完成的事情。

【讨论】:

  • 当使用IBackgroundJobClient 的实例时,我看不到任何可以指定队列名称的选项。 Enqueue方法不以队列名为参数
  • RecurringJob manager 已内置队列支持。如果您想立即在特定队列中排队,您需要使用IBackgroundJobClient.Create()EnqueuedStateIState 参数设置队列。或者,您可以在您正在调用的方法上添加 Queue 属性。但是,如果您不需要不同的队列并且只希望在同一个数据库中有两个 hangfire 实例,则不需要这些。
  • 非常有用。我以为队列可以用来隔离不同的应用程序,但后来我在 HF 中发现队列只在单个应用程序中有用。模式是解决问题的最佳方式。谢谢
  • Hangfire.MAMQSqlExtension 允许通过队列隔离作业。多台服务器之间无需代码共享
  • @XiaoguoGe 使您的库可用于 .Net Core
猜你喜欢
  • 2016-11-12
  • 2020-04-29
  • 2015-12-19
  • 1970-01-01
  • 2014-03-20
  • 2017-08-04
  • 2021-11-27
  • 2011-12-20
  • 1970-01-01
相关资源
最近更新 更多