禁用Hangfire BackgroundJob失败后的重新入队

50

有没有一种方法可以禁用失败的Hangfire BackgroundJob重新排队?

我们不希望再次执行失败的作业,因为这可能会导致问题。

5个回答

43

使用[AutomaticRetry(Attempts = 0)]解决了问题。


4
您可以添加 OnAttemptsExceeded = AttemptsExceededAction.Delete 来忽略这些作业并避免"失败作业"页面的异常。 - odinserj
1
这个解决方案是文档中建议的做法,但实际上,我在运行系统时没有看到任何区别。即使在我从定期作业中调用的方法上启用了此属性,我的失败作业仍会自动重试。其他人似乎也有同样的问题。 - Nate Jackson
8
如果使用 DI 容器,您必须将属性放在接口定义上而不是实现上。例如:interface IMyService { [AutomaticRetry(Attempts = 0)] void MyMethod(); } - Simon_Weaver

29
您可以使用以下属性对方法进行注释,使其在后台运行:
[AutomaticRetry(Attempts = 0)]

或者在全局范围内设置:

GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });

但是如何在每个作业的基础上实现这一点呢?假设您希望默认情况下进行重试,但某个作业以无法恢复的方式失败,您不希望它重试该特定作业。 - Douglas Gaskell

19

如果你使用 DI 容器和接口一起使用,你必须在接口定义上放置属性。

public interface IDataUpdater
{
    [Hangfire.AutomaticRetry(Attempts = 0, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
    void UpdateData();
}

将工作排入队列

Hangfire.RecurringJob.AddOrUpdate<IDataUpdater>(updater => updater.UpdateData(), Cron.Hourly);

只需在代码实现中随意抛出任何旧异常来测试它。如果您做得正确,您将在作业历史记录下看到这个异常已被“删除”。

在此输入图片描述


9
今天我碰到了这个问题,但是我想在 .NET API 应用程序中全局设置重试过滤器。
以下方式可行...
services.AddHangfire(configuration => {
            // Disable retry for failed jobs
            // https://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html?highlight=retry
            configuration.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
        });

7

我曾经遇到过类似的问题,并找到了解决方法。对我来说,使用全局过滤器不是一个选择。我正在使用asp.net core和一个简单的后台任务。由于某种原因,AutomaticRetryAttribute被忽略了。结果发现我添加任务的方式是解决这个问题的关键。我的应用程序中有类似的代码,这是导致问题的原因:

BackgroundJob.Enqueue<IMyJobService>(js => js.DoWork());

在我的IMyJobService实现中,我有以下代码:
[AutomaticRetry(Attempts = 0)]
public void DoWork()
{
    // I'm working hard here
}

我想到的解决方案是:
public MyTestController
{
    private readonly IMyJobService _myJobService;

    public MyTestClass(IMyJobService myJobService)
    {
        _myJobService = myJobService;
    }

    public ActionResult Work()
    {
        BackgroundJob.Enqueue(() => _myJobService.DoWork());
        return Ok();
    }
}

我不再依赖于BackgroundJob.Enqueue<T> 来注入我的 IMyJobService 实现,而是自己实现。基本上就是这样。希望能对某些人有所帮助。


3
我将AutomaticRetryAttribute应用于接口方法定义上,而不是实现方法上,这样解决了相同的问题。 - gjspaho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接