quartz jboss spring多个Web应用程序
我已成功地在我的应用程序中使用石英。 基本上,我在Jboss中运行的webapp1中捆绑了quartz 但是我们在jboss中运行了另一个webapp2,它也需要quartz作业 现在我需要做的是让quartz调度器作为某种服务在jboss中运行,这两个Web应用程序都应该能够 在单个quartz调度程序上注册他们的作业 下面是我的webapp1的相关spring配置,它一直在工作到现在quartz jboss spring多个Web应用程序,spring,jboss,datasource,quartz-scheduler,rmi,Spring,Jboss,Datasource,Quartz Scheduler,Rmi,我已成功地在我的应用程序中使用石英。 基本上,我在Jboss中运行的webapp1中捆绑了quartz 但是我们在jboss中运行了另一个webapp2,它也需要quartz作业 现在我需要做的是让quartz调度器作为某种服务在jboss中运行,这两个Web应用程序都应该能够 在单个quartz调度程序上注册他们的作业 下面是我的webapp1的相关spring配置,它一直在工作到现在 <bean id="qtzScheduler" class="org.springframew
<bean id="qtzScheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource">
<ref bean="jndiDataSource" />
</property>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="schedulerName" value="webapp1" />
</bean>
<bean id="wrapperScheduler" class="uk.fa.quartz.schedule.ServiceScheduler">
<property name="scheduler">
<ref bean="qtzScheduler" />
</property>
</bean>
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/FmManagerDS</value>
</property>
</bean>
现在我不想在webapp2中再次定义相同的调度器,这将导致jboss中运行2Quartz调度器
有人知道怎么做吗?
我在互联网上看到了一个例子,如下所示,我认为这是我想要的。
但是我不明白如何使用spring源中定义的数据源将其与我的系统集成。
如果有人可以共享配置或在internet上为我指出正确的资源,我将不胜感激。您所指的说明了如何访问Quartz scheduler服务。我从未使用过这种方法,但基本上你让JBoss来处理你的调度程序、数据源和它周围的一切。这使得利用作业调度变得非常容易,而不需要所有的配置工作,但灵活性不高,应用程序不再是自包含的
在您的案例中,我看到了两个值得研究的选项:
群集石英调度器
将两个web应用程序配置为。两个应用程序将共享同一个数据库,并将运行彼此定义的作业。由于以下几个原因,这可能不是您的选择:
- 两个应用程序必须能够运行彼此定义的作业-例如,作业类必须在类路径上可用
- 您仍然需要在两个应用程序中定义Quartz配置(您可以轻松共享配置,例如,通过将XML配置提取到单独的文件中)
- 两个应用程序都将维护单独的线程池
请参阅:。最后,我有时间为所有其他可能不得不使用Quartz作为jboss中运行的服务的人写下这一切。 但是@Tomasz在他的回答中提到的其他选择也可以尝试 请注意,如果您试图从绑定它的JBoss服务器外部检索它,您将得到一个空引用。如果您有这样的要求,您可能需要考虑使用石英的RMI支持。p> 1) 首先,确保删除jboss/[profile]/lib或jboss发行版附带的quartz.rar中quartz的任何现有版本 2) 请将您的quartz.1.8.3.jar和quartz-jboss.1.8.jar放入acccesmanager/[profile]/lib 3) 下面是quartz-service.xml的代码,它需要放在jboss部署文件夹中,该文件夹将启动quartz调度器:
<server>
<mbean code="org.quartz.ee.jmx.jboss.QuartzService"
name="user:service=QuartzService,name=QuartzService">
<attribute name="JndiName">Quartz</attribute>
<attribute name="Properties">
org.quartz.scheduler.instanceName = BGSScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.xaTransacted = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = QUARTZ
org.quartz.dataSource.QUARTZ.jndiURL = java:FmManagerDS
org.quartz.jobStore.nonManagedTXDataSource = QUARTZ_NO_TX
org.quartz.dataSource.QUARTZ_NO_TX.jndiURL = java:FmManagerDS
</attribute>
<depends>jboss.jca:service=DataSourceBinding,name=FmManagerDS</depends>
</mbean>
</server>
下面是将spring应用程序上下文传递给EmailJob的代码,以便我们可以访问bean和其他内容。
为了实现这一点,我们需要实现ApplicationContextAware接口,以便applicationContext可用,然后也可以使用
推入schedulerContext。请确保我们不会将applicationContext放入JobdataMap,以防您使用JDBC存储,因为它会导致序列化问题
serviceScheduler.getScheduler().getContext().put("applicationContext", ctx);
serviceScheduler.scheduleCronJob(job, "test" + t.toString(), ServiceScheduler.DEFAULT_TRIGGER_GROUP, cronExpression);
其他不使用wrapperscheduler的人也可以使用下面的方法将quartz的句柄直接输入到他们的代码中
InitialContext ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
ScheduleJob job = new ScheduleJob(EmailJob.class.getCanonicalName() +t.toString(), Executor.class);
scheduler.scheduleJob(job, trigger);
在电子邮件作业类中,您可以使用下面的内容获取applicationContext
applicationContext = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
//get spring bean and do the necessary stuff
另一件重要的事情是,由于quartz schedler在Web应用程序外部运行,quartz如果在war内部,则无法启动jobclass。它需要位于jboss/[profile]中的共享jar中/lib.谢谢你给我一个headthrough。这是否意味着我必须再创建一个webapp3作为quartz服务器,webapp1和webapp2将使用它,或者我可以让quartz服务器在其中一个webapp1中运行,让webapp2使用相同的服务器。但是在这两种情况下,我认为作业类对调用的webapp都不可用。你可以吗让我们了解一下这一点?@Rips:你说得对,你可以创建
webapp3
,或者使用现有的一个应用程序来托管Quartz。关于类路径问题-如果没有这些问题,您将永远无法逃脱-在所有情况下,运行作业的JVM/classloader都必须能够访问作业类。我们在jboss中没有使用统一的类加载器,因此一个webapp中的类与另一个webapp2中的类之间不存在可见性。这是否意味着所有作业类及其用于业务逻辑的类都需要放在承载quartz的webapp中?那我就没有别的选择了吗?
serviceScheduler.getScheduler().getContext().put("applicationContext", ctx);
serviceScheduler.scheduleCronJob(job, "test" + t.toString(), ServiceScheduler.DEFAULT_TRIGGER_GROUP, cronExpression);
InitialContext ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
ScheduleJob job = new ScheduleJob(EmailJob.class.getCanonicalName() +t.toString(), Executor.class);
scheduler.scheduleJob(job, trigger);
applicationContext = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
//get spring bean and do the necessary stuff