让 Quartz.net 忽略失火 [英] Getting Quartz.net to ignore misfires

查看:48
本文介绍了让 Quartz.net 忽略失火的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个 Windows 服务,它正在执行一个计划任务,该任务使用 Quartz.net 定期(每分钟一次)处理命令队列(来自旧系统)

I'm building a windows service which is performing a scheduled task which processes a queue of commands (from a legacy system) at a regular interval (once per min) using Quartz.net

如果任务花费的时间超过 1 分钟,这在某些情况下是不寻常的,但在某些情况下是可能的,我希望它简单地忽略它错过的触发器.

If the task takes longer than 1 min, which would be unusual but possible under certain circumstances, I'd like it to simple ignore the triggers it missed firing.

但是我似乎无法做到这一点.它进行处理,然后快速连续快速触发它错过的所有触发器.据我了解,您可以为失火设置阈值,但我似乎无法使其正常工作.

However I can't seem to get this to happen. It does the processing and then quickly fires all the triggers it missed in quick succession. As I understand you can set a threshold for the misfires but I don't seem to be-able to get this working.

我在作业上使用 [DisallowConcurrentExecution()] 以确保在任何时候只有一个作业实例正在运行.

I'm using [DisallowConcurrentExecution()] on the Job to ensure only one instance of the job is running at any one time.

以下是几个片段.首先传入一些配置信息 - 这是您设置失火阈值的方式吗?

Below are a couple of snippets. First passing in some config info - is this how you set the misfire threshold?

    NameValueCollection config = new NameValueCollection();
    config.Add("quartz.jobStore.misfireThreshold", "600000");

    schedFact = new StdSchedulerFactory(config);

使用我认为正确的 Ignore misfires 设置构建触发器:

Building a trigger with what I assume to be the correct setting of Ignore misfires:

    var trigger = TriggerBuilder.Create()
                    .WithIdentity("trigger1", "group1")
                    .StartNow()
                    .WithSimpleSchedule(   x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                    .WithIntervalInSeconds(60)
                    .RepeatForever())
                    .Build();

非常感谢您的想法.

工作代码:在这一点上只是玩一些粗略的想法,所以只需在控制台应用程序中运行并随机延迟一项工作,以便它在刚刚设置为 10 秒的间隔内拍摄.经过几次延迟后,所有备份的失火都快速连续触发.

Code for the Job: Just playing with rough ideas at this point so just running in a console app and randomly delaying a job so it shoots over the interval which is just set at 10 seconds for this. All the backed up misfires fire in quick succession after a couple of delays.

[DisallowConcurrentExecution()]
public class SomeJob : IJob
{
    public SomeJob() { }
    public void Execute(IJobExecutionContext context)
    {
        Random rnd = new Random(DateTime.UtcNow.Second);
        int delay = rnd.Next(2);
        Console.WriteLine("Executing Job with delay of "+ delay + "  at " + DateTime.UtcNow.ToString());

        if (delay == 1)
        {
            System.Threading.Thread.Sleep(1000 * 25); // sleep for 25 seconds
        }
    }
}





Example console output:
Executing Job with delay of 1  at 21/05/2015 21:27:17
Executing Job with delay of 1  at 21/05/2015 21:27:42
Executing Job with delay of 0  at 21/05/2015 21:28:07 <-- stacked misfires
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:16
Executing Job with delay of 0  at 21/05/2015 21:28:26
Executing Job with delay of 1  at 21/05/2015 21:28:36
Executing Job with delay of 0  at 21/05/2015 21:29:01
Executing Job with delay of 0  at 21/05/2015 21:29:01
Executing Job with delay of 1  at 21/05/2015 21:29:06

推荐答案

WithMisfireHandlingInstructionIgnoreMisfires() 是你想要的错误方法,这并不意味着作业不会触发失火,这意味着它将尽快触发所有错过的触发器,然后返回到正常计划.这就是你所看到的.

WithMisfireHandlingInstructionIgnoreMisfires() is the wrong method for what you want, it doesn't mean the job will not trigger misfires, it means it will fire all triggers that were missed as soon as possible and will then go back to ordinary schedule. Which is what you see happening.

您需要的是WithMisfireHandlingInstructionNextWithRemainingCount().这将通知调度程序忽略失火并等待下一个调度时间.失火策略可能有点令人困惑,要获得简洁的解释,请查看这里(它是针对 java 调度程序的,但它没关系).

What you need is WithMisfireHandlingInstructionNextWithRemainingCount(). This will signal the scheduler to ignore misfires and wait for the next scheduled time. Misfiring strategies can be a bit confusing, for a concise explanation look here (it's for the java scheduler but it doesn't matter).

即使采用正确的策略,您也需要了解失火阈值的工作原理 - 如果您弄错了,您的失火触发器可能仍会触发.

Even with the right strategy, you need to understand how the misfire threshold works- if you get it wrong your misfired trigger may still fire.

来自文档:失火是触发器必须错过下一次触发时间的时间跨度,以便将其视为失火"并因此应用其失火指令".

您已将该值设置为 600000 毫秒(该值适用于所有触发器,遗憾的是每个触发器没有阈值)- 仅当触发器触发 600000 毫秒 之后 它应该被触发的时间.您可以根据需要降低或增加它.

You've set the value to 600000 milliseconds (and this value is for all triggers, unfortunately there is no threshold per trigger)- the misfire strategy will only be applied if your trigger fires 600000 milliseconds after the time it should have been fired. You can lower or increase it according to your requirement.

有关失火阈值的更多信息,请阅读此处.

For more about the misfire threshold, read here.

这篇关于让 Quartz.net 忽略失火的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆