Quartz任务调度中Misfire处理机制详解

Quartz任务调度中Misfire处理机制详解

问题背景

在Quartz调度框架中,当任务被暂停后重新启动时,被暂停期间积压的任务会连续多次调用job中的execute方法。如果任务处理时间过长,会导致系统资源紧张甚至崩溃。

Misfire机制解析

CronTrigger处理规则

指令行为描述
withMisfireHandlingInstructionDoNothing不立即触发执行,等待下次Cron触发时刻按正常频率执行
withMisfireHandlingInstructionIgnoreMisfires立即从第一个错过的时间点开始执行,补做所有错过周期后恢复正常频率
withMisfireHandlingInstructionFireAndProceed立即以当前时间触发一次,然后按正常Cron频率执行

SimpleTrigger处理规则

指令行为描述
withMisfireHandlingInstructionFireNow立即执行,完成剩余周期次数
withMisfireHandlingInstructionIgnoreMisfires从第一个错过时间点开始补做所有周期
withMisfireHandlingInstructionNextWithExistingCount不立即执行,等待下次触发时刻完成剩余次数
withMisfireHandlingInstructionNowWithExistingCount立即执行完成剩余次数
withMisfireHandlingInstructionNextWithRemainingCount不立即执行,等待下次触发完成剩余次数
withMisfireHandlingInstructionNowWithRemainingCount立即执行完成剩余次数

解决方案

配置调整

quartz.properties中添加:

# 设置misfire阈值(毫秒),超过此值将不处理misfire
org.quartz.jobStore.misfireThreshold = 5000

```java
public String add() throws IOException, SchedulerException {
    String cronExp = job.getCronExpression();
    Scheduler scheduler = schedulerFactoryBean.getScheduler();
    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
    
    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
    
    if (null == trigger) {
        // 新建任务
        JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
            .withIdentity(job.getJobName(), job.getJobGroup()).build();
        jobDetail.getJobDataMap().put("scheduleJob", job);
        
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
            .cronSchedule(job.getCronExpression())
            .withMisfireHandlingInstructionDoNothing();
            
        trigger = TriggerBuilder.newTrigger()
            .withIdentity(job.getJobName(), job.getJobGroup())
            .withSchedule(scheduleBuilder).build();
            
        scheduler.scheduleJob(jobDetail, trigger);
    } else {
        // 更新现有任务
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
            .cronSchedule(job.getCronExpression())
            .withMisfireHandlingInstructionDoNothing();
            
        trigger = trigger.getTriggerBuilder()
            .withIdentity(triggerKey)
            .withSchedule(scheduleBuilder).build();
            
        scheduler.rescheduleJob(triggerKey, trigger);
    }
    return SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值