我的网络应用程序有一个有趣的问题。最近,我们遇到了一个巨大的并发问题,Quartz 在数百个线程中同时触发同一个 java 类,导致数据库争用并完全锁定我们的应用程序。在我们能够解决根本问题之前,我必须将数据库表 qrtz_triggers 上的所有 Misfire_instr 设置为“1”(不要重新触发失火),以使应用程序启动并为正常流量提供服务。然后,我们手动缓慢地关闭错过的时间表,以避免并发问题。
我已经解决了并发问题,并准备好热部署我们的应用程序,但担心如果我将misfire_instr设置回2(重新触发misfires),错过的时间表将根据prev_fire_time再次重新触发?
建议的解决方案 - 将 prev_fire_time 设置为 next_fire_time 之前几分钟,以便它认为最后的时间表已结束。如果 prev_fire_time 在 cron 表达式表示的最后时间之前,我的假设是否正确?
我还看到尚未运行的计划在列中有 -1,这是新计划的默认值,也许我应该使用这个值?
由于我们需要立即执行此操作,因此我决定尝试使用 -1 作为 prev_fire_time 值(并将触发器更新回 2)。这符合预期。
这是我最近想到的。 MISFIRE_INSTR 列中的值的含义部分取决于触发器的类型。请参阅 Quartz 客户端源代码,了解数字列值到含义的友好映射,但这里是一个摘要:
对于所有触发器:
SmartPolicy = 0 (usually 'fire now')
IgnoreMisfirePolicy = -1
对于简单触发器:
FireNow = 1
RescheduleNowWithExistingRepeatCount = 2
RescheduleNowWithRemainingRepeatCount = 3
RescheduleNextWithRemainingCount = 4
RescheduleNextWithExistingCount = 5
对于 CronTrigger/CalendarIntervalTrigger/DailyTimeIntervalTrigger:
FireOnceNow = 1
DoNothing = 2