首页 > 解决方案 > 在 Tomcat 中使用石英调度程序和多个 WAR 中的作业

问题描述

我正在处理一个中型 Java 9 项目,该项目必须在单个 Tomcat 9 环境中的多个 WAR 中运行多个 Quartz 2.3.1 作业。

  1. 这些作业是否应该使用单个 JDBCJobStore 处理并使用单个调度程序运行?我很好奇,因为网络上没有任何示例可以从多个 WAR 运行作业。

我创建了一个 ClassLoadHelper,其中各种 Webapp 类加载器在部署/取消部署时注册/注销自己,并从它们的类加载器加载作业类。

  1. 如果在部署某些 WebApp 时启动调度程序,我会收到以下异常:
org.quartz.SchedulerConfigException: Failure occured during job recovery.
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:697) ~[quartz-2.3.1.jar:?]
        at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:539) ~[quartz-2.3.1.jar:?]
        at org.quartz.core.QuartzScheduler$1.run(QuartzScheduler.java:564) [quartz-2.3.1.jar:?]
        at java.lang.Thread.run(Thread.java:844) [?:?]
Caused by: org.quartz.JobPersistenceException: Couldn't store trigger 'TestTrigger' for 'TestJob' job:Couldn't retrieve job because a required class was not found: org.myorg.test.TestJob
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1228) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.doUpdateOfMisfiredTrigger(JobStoreSupport.java:1042) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:991) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:871) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$1.executeVoid(JobStoreSupport.java:843) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3780) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3778) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3864) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:839) ~[quartz-2.3.1.jar:?]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:695) ~[quartz-2.3.1.jar:?]
        ... 3 more
Caused by: org.quartz.JobPersistenceException: Couldn't retrieve job because a required class was not found

没关系,正在部署第二个 webapp。但是调度器启动卡住了,它不会启动其他类可用的作业。它不是试图稍后开始丢失的工作。有没有办法将缺少类的作业置于 ERROR 状态并继续调度程序启动?或者调度器要在所有 webapps 部署后启动?如何处理将在 Tomcat 关闭时启动的作业?

  1. 如果作业未处于 WAITING 状态(例如暂停或错误),则会跳过失败的作业恢复。是否可以暂停 SchedulerListener 的 schedulerStartup() 方法中的所有触发器以确保调度程序启动不会失败?webapps 应该在部署/取消部署时暂停/恢复他们的工作吗?

  2. 作业应由用户禁用/启用,即使作业在调度程序内处于 ERROR 或 PAUSED_becauseClassIsMissing 状态,也必须保留此设置。我需要一些外部管理来存储它吗?

  3. 一个可能的解决方案是,如果找不到作业类,ClassLoadHelper 可以返回 NoOpJob。除了用这种方法触发恢复失败之外,我还会破坏任何东西吗?

标签: javatomcatquartz-scheduler

解决方案


推荐阅读