如何让一个 Hangfire 实例 运行 只有它自己的工作?

How to make a Hangfire instance run its own jobs only?

我在使用相同数据库的两台服务器上有几个 Hangfire 运行ning 实例。每个实例都根据基于服务器名称的某些条件提交作业 运行,这样就不会有两个实例 运行 相同的作业。我注意到它们 运行 正在执行相同的作业,这意味着当一个实例正在 运行 时,它会选择数据库队列中的任何作业,而不管它是否提交了该作业。我想在最新的版本1.6.x中,每个工作都是独一无二的。这似乎并不意味着它 运行 仅在创建它的实例上?

如何让每个实例只提交 运行 个作业?

您需要使用队列select哪个服务器处理特定的作业。

想法是通过指定队列来对作业进行分类。然后对于每个服务器,您将指定他们监视的队列。

在我看来,唯一的问题是为作业选择队列并不简单(除非您使用的是 RecurringJobs)。

服务器配置

当你为服务器启动 Hangfire 实例时,使用 Queues BackgroundJobServerOptions 根据 the documentation:

app.UseHangfireServer(new BackgroundJobServerOptions()
    {
        // order defines priority
        // beware that queue names should be lowercase only
        Queues = new [] { "critical", "default", "myqueueformyserver" } 
    });

为作业选择队列

有两种情况:

  1. 经常性工作:RecurringJob.AddOrUpdate("MyFirstRecurringJob", () => myClass.myMethod(), Cron.Minutely(), null, "myqueueformyserver");

  2. BackgroundJobs:您无法在入队时指定作业队列 (Hangfire.BackgroundJob.Enqueue(() => myClass.myMethod());),没有此选项。解决方案是使用方法或 class 属性。 Hangfire 提供了一个 QueueAttribute:
    [Queue("myqueueformyserver")] public void myMethod() { }

如果我理解您的要求,静态 QueueAttribute 将不适合您,因为您想要动态分配队列。我遇到了同样的情况,并在 code of the QueueAttribute.

的启发下创建了自己的属性

看起来像那样(适应你的willing/needs)

public class MyQueueAttribute : JobFilterAttribute, IElectStateFilter
{
    public MyQueueAttribute(string paramQueue)
    {
        ParamQueue = paramQueue;
    }

    public string ParamQueue { get; }

    public void OnStateElection(ElectStateContext context)
    {
        var enqueuedState = context.CandidateState as EnqueuedState;
        if (enqueuedState != null)
        {
            enqueuedState.Queue = string.Concat(Environment.MachineName.ToLower(), 
                                                ParamQueue);
        }
    }
}