如果命令已经在处理,我如何“丢弃”队列中的新任务?

问题描述 投票:0回答:1

我在 Windows 服务上设置了 Hangfire,我基本上从

_server = new BackgroundJobServer();

开始

我配置了大约 30 个命令,每个命令都有不同的命令/参数(我相信这是一个基本设置)。

每项任务必须每 1 分钟连续执行一次。因此,我将 Cron 和Frequency 列分别设置为

*/1 * * * *
Every 1 minutes

问题是这样的:如果我对 30 个命令进行排队,其中一些命令需要超过 1 分钟(即由于要执行的繁重进程而需要 10 分钟),它会连续对每个任务(以及已经在处理的任务)进行排队),导致任务阻塞/无限排队,1 分钟内无法出队。

如何解决它以避免已处理任务重新排队?

谢谢

c# .net hangfire
1个回答
0
投票

有几种方法可以解决这个问题,具体取决于您的设置,但最好的方法可能是解决您的吞吐量问题。如果不使各个作业在执行时间上更加高效或更稳定,您可以:

  1. 提高作业吞吐量。您可以添加更多并行化,以确保作业在队列中的等待时间不会超过您的要求。要实现此目的,您可以增加

    WorkerCount
    服务器配置的
    Hangfire
    ,从而使更多作业能够在单个实例上并行运行,或者您也可以添加服务器应用程序的更多实例。当然,您的代码和部署场景需要支持这一点。

  2. 通过不每分钟执行所有操作来减少总作业队列。

  3. 这不是我的首选方法,但您可以在作业方法的开头使用

    Hangfire
    监控 Api 来删除同一作业的其他排队实例。这有几个先决条件。首先,每个作业都需要一个由您控制的唯一标识符。这意味着如果您使用不同的参数调用相同的方法,那么每个方法调用都需要一个唯一的 Hangfire 名称。其次,您必须将
    IBackgroundJobClient
    的实例注入到您的作业中,以便每个作业都可以管理队列。第三,方法本身必须以某种方式知道它的调用方式。您可能希望将
    PerformContext
    作为方法参数包含在内,以便作业对自身有一些了解。最后,您可以获取对
    Hangfire
    监控 api 的引用,并使用以下内容删除重复的作业:

IMonitoringApi api = JobStorage.Current.GetMonitoringApi();
var enqueuedJobs = api.EnqueuedJobs("yourQueueName", 0, 50);

// The way you filter in the where clause is up to you here. You'll have access to invocation data for each job so you could filter on parameters supplied matching those of the current method running
foreach(var job in enqueuedJobs.Where(j => j.Value.Job.ToString() == jobName))
{
    _jobClient.Delete(job.Key);
}
© www.soinside.com 2019 - 2024. All rights reserved.