2012-08-13 97 views
1

我已經成功地在我的應用中使用石英。 基本上我在webapp1內部運行Jboss內部的石英。石英jboss彈簧多個webapps

但是我們必須在一個需要有石英工作以及

現在我需要做的JBoss運行的另一個webapp2的是有石英調度在JBoss運行的某種服務兩者的web應用應該能夠 在單石英調度程序上註冊他們的工作。

下面是我對webapp1的相關spring配置,它一直在工作到現在。

<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> 

時,我有安排工作,代碼如下所示:

WrapperScheduler scheduler = (WrapperScheduler) ctx.getBean("wrapperScheduler"); 
    scheduler.scheduleCronJob(job, jobName + "CronTrigger", WrapperScheduler.TRIGGER_GROUP, cronExpression); 

現在我不想定義webapp2的再次同一個調度,這將導致2石英調度在JBoss運行。

有人可以知道該怎麼做嗎? 我在互聯網上看到一個例子,如下面的Link,我認爲它正在做我想做的事。 但我不明白我可以如何使用我的spring源中定義的數據源將其與我的系統集成。 如果有人可以分享配置或指向我在互聯網上正確的資源,我會非常感謝。

回答

0

最後,我有時間寫下所有其他人可能不得不使用Quartz作爲在jboss中運行的服務。 但他的@Tomasz回答中提到的其他選項也可以嘗試。

請注意,如果您嘗試從綁定綁定的JBoss服務器之外檢索到空引用,您將收到空引用。如果你有這樣的要求,你可能會考慮使用Quartz的RMI支持。

1)首先確保你刪除了jboss/[profile]/lib中的任何現有版本的quartz,或者是與jboss發行版一起提供的quartz.rar。

2)請您quartz.1.8.3.jar &石英jboss.1.8.jar到acccesmanager/[資料]/lib中

3)下面是石英service.xml中,其需要的代碼被放置在其中將啓動Quartz調度了JBoss部署文件夾:

<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> 

] 大部分的東西是自我解釋,或者你可以在Quartz Configuration 關鍵的一點是要注意的是石英需要獲得更多關於這方面的詳細信息2個數據源。一個是容器管理的數據源 - 與之相同在jboss * -ds.xml中定義(在我的情況下是java:FmManagerDS)。 如果'org.quartz.jobStore.dataSource'是XA,那麼將'org.quartz.jobStore.nonManagedTXDataSource'設置爲非XA數據源(對於同一個數據庫)。否則,您可以將它們設置爲相同。

在Spring的ApplicationContext

然後,我不得不石英的手柄,這樣我可以注入到wrapperScheduler.Code爲低於

<bean id="quartzScheduler" class="org.springframework.jndi.JndiObjectFactoryBean"> 
      <property name="jndiName"> 
       <value>Quartz</value> 
      </property> 
    </bean> 

<bean id="wrapperScheduler" class="k.fa.quartz.schedule.ServiceScheduler"> 
      <property name="scheduler"> 
       <ref bean="quartzScheduler" /> 
      </property> 
    </bean> 

然後,我們可以使用下面

Timestamp t = new Timestamp (System.currentTimeMillis()); 
ScheduleJob job = new ScheduleJob(EmailJob.class.getCanonicalName() +t.toString(), EmailJob.class); 
調度作業

下面是將spring applicationContext傳遞給EmailJob的代碼,以便我們可以訪問bean和其他東西。 爲了實現這一點,我們需要實現ApplicationContextAware接口,以便applicationContext可用,然後將 推入schedulerContext.Please確保我們不會將ApplicationContext放入JobdataMap,因爲它會導致序列化問題。誰不使用wrapperscheduler

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 = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY); 
     //get spring bean and do the necessary stuff 

另一個重要的事情是,由於石英切割機運行在網絡應用程序之外,如果石英在戰爭中,它將無法發射工作類。它需要位於jboss/[profile]/lib中的共享jar中。

2

您提到的link解釋瞭如何訪問Quartz調度程序服務built into JBoss。我從來沒有使用這種方法,但基本上你讓JBoss處理你的調度器,數據源和它周圍的一切。這使得非常容易地利用作業調度而無需所有配置忙碌 - 但不是很靈活,並且您的應用程序不再是自包含的。

在你的情況下,我看到兩個選項值得探討:

集羣Quartz調度

配置您的兩個Web應用程序run in a cluster。這兩個應用程序將共享相同的數據庫,並將運行相互定義的作業。由於以下幾個原因,這可能不適合您:

  • 這兩個應用程序必須能夠運行彼此定義的作業 - 例如,作業類必須提供在CLASSPATH

  • ,你仍然需要在這兩個應用程序定義石英配置(您可以輕鬆地共享配置雖然,例如通過提取XML配置成一個單獨的文件)

  • 兩個應用程序將保持單獨的線程池

羣集更適合在多臺機器上運行的同類應用程序,而不是在單個節點上運行的異構應用程序。

遠程調度

石英具有通過一個built-in support for remote schedulers。基本上,一個應用程序託管完整的Quartz服務器,而另一個連接到該服務器。這對你來說似乎是一個更好的方法(我們稱之爲「主從」),因爲只有一個應用程序管理調度程序,而另一個應用程序使用現有調度程序。

參見:RemoteScheduler

+0

感謝您給我一個通道。這是否意味着我將不得不創建另一個webapp3,它將充當石英服務器,並且webapp1&webapp2將使用它,或者我可以在webapp1之一中運行石英服務器,並使webapp2使用但是在這兩種情況下,我認爲jobclasses不會被調用webapp使用。請給我們一些啓示? – Rips 2012-08-13 21:47:52

+0

@Rips:您是對的,您可以創建'webapp3'或使用現有應用程序之一來託管Quartz。關於CLASSPATH問題 - 如果沒有它們,您將永遠無法離開 - 運行作業的JVM/classloader必須有權訪問作業類 - 在所有情況下。 – 2012-08-13 21:51:34

+0

我們沒有在jboss中使用統一的類加載器,因此一個webapp中的類不會在其他webapp2中的內容中具有可見性。 這是否意味着所有工作類和它用於業務邏輯的類都需要放入托管石英的Web應用程序中。 ?那麼我還沒有其他選擇嗎? – Rips 2012-08-13 22:35:17