【发布时间】:2012-07-06 12:10:01
【问题描述】:
我们有一个基于石英的调度程序应用程序,它每分钟运行大约 1000 个作业,这些作业均匀分布在每分钟的几秒钟内,即每秒大约 16-17 个作业。理想情况下,这 16-17 个作业应该同时触发,但是我们的第一条语句(它只记录执行时间)的执行方法被调用得很晚。例如 假设我们从 05:00 到 05:04 每分钟安排了 1000 个作业。因此,理想情况下,安排在 05:03:50 的作业应该在 05:03:50 记录执行方法的第一条语句,但是,它是在大约 05:06:38 执行的。我已经跟踪了大约 15-20 毫秒的预定作业所花费的时间。这个计划的作业足够快,因为我们只是在 ActiveMQ 队列上发送消息。 我们已将石英的线程数指定为 100,甚至尝试将其增加到 200 或更多,但没有任何收获。我们注意到的另一件事是,调度程序的日志在前 1 分钟后是连续的,即
[Quartz_Worker_28] <Some log statement>
..
..
[Quartz_Worker_29] <Some log statement>
..
..
[Quartz_Worker_30] <Some log statement>
..
..
所以它表明在一段时间后,quartz 运行线程几乎是连续的。这可能是由于将作业完成通知到持久性存储(在这种情况下是一个单独的 postgres 数据库)和/或上下文切换所花费的时间。
这种奇怪行为背后的原因是什么?
编辑:更详细的日志
[06/07/12 10:08:37:192][QuartzScheduler_Worker-34][INFO] org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger [<trigger_name>] fired job [<job_name>] scheduled at: 06-07-2012 10:08:33.458, next scheduled at: 06-07-2012 10:34:53.000
[06/07/12 10:08:37:192][QuartzScheduler_Worker-34][INFO] <my_package>.scheduler.quartz.ScheduledLocateJob - execute begin--------- ScheduledLocateJob with key: <job_name> started at Fri Jul 06 10:08:37 EDT 2012
[06/07/12 10:08:37:192][QuartzScheduler_Worker-34][INFO] <my_package>.scheduler.quartz.ScheduledLocateJob <some log statement>
[06/07/12 10:08:37:192][QuartzScheduler_Worker-34][INFO] <my_package>.scheduler.quartz.ScheduledLocateJob <some log statement>
[06/07/12 10:08:37:192][QuartzScheduler_Worker-34][INFO] <my_package>.scheduler.quartz.ScheduledLocateJob <some log statement>
[06/07/12 10:08:37:220][QuartzScheduler_Worker-34][INFO] <my_package>.scheduler.quartz.ScheduledLocateJob - execute end--------- ScheduledLocateJob with key: <job_name> ended at Fri Jul 06 10:08:37 EDT 2012
[06/07/12 10:08:37:220][QuartzScheduler_Worker-34][INFO] org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger [<trigger_name>] completed firing job [<job_name>] with resulting trigger instruction code: DO NOTHING. Next scheduled at: 06-07-2012 10:34:53.000
我对上述日志的这一部分表示怀疑
scheduled at: 06-07-2012 10:08:33.458, next scheduled at: 06-07-2012 10:34:53.000
因为这项工作计划在 10:04:53 进行,但它在 10:08:33 触发,但石英仍然认为它没有触发失败。不应该是失火吗?
【问题讨论】:
-
你能在这个进程运行时发布你的线程的线程转储吗?将其发布在这里或作为 Gist/pastebin。也可以考虑使用
LoggingTriggerHistoryPlugin -
我已经说明了我们的调度程序应用程序转储的日志示例,但是,我没有石英线程转储,因为我们还没有使用任何历史插件。启用历史插件后,我会尝试获取转储。
-
我的意思是 JVM 线程转储(使用像
jps或jvisualvm这样的工具),插件不是必需的。我想看看 Quartz 线程在此期间在做什么。 -
其实我改了内容。这里是link。
-
感谢您提供此详细信息。您如何为
ScheduledLocateJob定义触发器?这个工作不是有状态的吗? (它实现了哪些接口,哪些注解)确实你的工作只由一个线程执行,其余的都是空闲的。
标签: java scheduling quartz-scheduler