quartz集群環(huán)境下的最終解決方案

      網(wǎng)友投稿 928 2022-05-30

      在集群環(huán)境下,大家會(huì)碰到一直困擾的問(wèn)題,即多個(gè)?APP?下如何用?quartz?協(xié)調(diào)處理自動(dòng)化?JOB?。

      大家想象一下,現(xiàn)在有?A?,?B?,?C3?臺(tái)機(jī)器同時(shí)作為集群服務(wù)器對(duì)外統(tǒng)一提供?SERVICE?:

      A?,?B?,?C 3?臺(tái)機(jī)器上各有一個(gè)?QUARTZ?,他們會(huì)按照即定的?SCHEDULE?自動(dòng)執(zhí)行各自的任務(wù)。

      我們先不說(shuō)實(shí)現(xiàn)什么功能,就說(shuō)這樣的架構(gòu)其實(shí)有點(diǎn)像多線程。

      那多線程里就會(huì)存在“資源競(jìng)爭(zhēng)”的問(wèn)題,即可能產(chǎn)生臟讀,臟寫,由于三臺(tái)?APP SERVER?里都有QUARTZ?,因此會(huì)存在重復(fù)處理?TASK?的現(xiàn)象。

      一般外面的解決方案是只在一臺(tái)?APP?上裝?QUARTZ?,其它兩臺(tái)不裝,這樣集群就形同虛設(shè)了;

      另一種解決方案是動(dòng)代碼,這樣就要影響到原來(lái)已經(jīng)寫好的?QUARTZ JOB?的代碼了,這對(duì)程序開發(fā)人員來(lái)說(shuō)比較痛苦;

      本人仔細(xì)看了一下?Spring?的結(jié)構(gòu)和?QUARTZ?的文檔,結(jié)合?Quartz?自身可以實(shí)例化進(jìn)數(shù)據(jù)的特性找到了相關(guān)的解決方案。

      本方案優(yōu)點(diǎn):

      每臺(tái)作為集群點(diǎn)的?APP SERVER?上都可以布署?QUARTZ?;

      QUARTZ?的?TASK?(?12?張表)實(shí)例化如數(shù)據(jù)庫(kù),基于數(shù)據(jù)庫(kù)引擎及?High-Available?的策略(集群的一種策略)自動(dòng)協(xié)調(diào)每個(gè)節(jié)點(diǎn)的?QUARTZ?,當(dāng)任一一節(jié)點(diǎn)的?QUARTZ?非正常關(guān)閉或出錯(cuò)時(shí),另幾個(gè)節(jié)點(diǎn)的?QUARTZ?會(huì)自動(dòng)啟動(dòng);

      無(wú)需開發(fā)人員更改原已經(jīng)實(shí)現(xiàn)的?QUARTZ?,使用?SPRING+?類反射的機(jī)制對(duì)原有程序作切面重構(gòu);

      本人也事先搜索了一些資料,發(fā)覺所有目前在?GOOGLE?上或者在各大論壇里提供的解決方案,要么是只解決了一部分,要么是錯(cuò)誤的,要么是版本太老,要么就是完全抄別人的。

      尤其是在使用?QUARTZ+SPRING?對(duì)數(shù)據(jù)庫(kù)對(duì)象作實(shí)例化時(shí)會(huì)拋錯(cuò)(源于?SPRING?的一個(gè)?BUG?),目前網(wǎng)上的解決方案全部是錯(cuò)的或者干脆沒(méi)說(shuō),本人在此方案中也會(huì)提出如何解決。

      解決方案:

      把?QUARTZ?的?TASK?實(shí)例化進(jìn)數(shù)據(jù)庫(kù),?QUARTZ?只有實(shí)例化進(jìn)入數(shù)據(jù)庫(kù)后才能做集群,外面的解決方案說(shuō)實(shí)例化在內(nèi)存里全部是錯(cuò)的,把quartz-1.8.4/docs/dbTables/tables_oracle.sql?在?ORACLE9I2?及以上版本中執(zhí)行一下會(huì)生成?12?張表;

      生成?quartz.properties?文件,把它放在工程的?src?目錄下,使其能夠被編譯時(shí)納入?class path?。

      一般我們的開發(fā)人員都喜歡使用?SPRING+QUARTZ?,因此這個(gè)?quartz.properties?都不用怎么去寫,但是在集群方案中?quartz.properties?必寫,如果不寫?quartz?會(huì)調(diào)用自身?jar?包中的?quartz.properties?作為默認(rèn)屬性文件,同時(shí)修改?quartz.xml?文件。

      Quartz.xml?文件的內(nèi)容?:

      quartz.properties?文件的內(nèi)容:

      org.quartz.scheduler.instanceName = mapScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate org.quartz.jobStore.dataSource = myXADS org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = true org.quartz.dataSource.myXADS.jndiURL=jdbc/TestQuartzDS org.quartz.dataSource.myXADS.jndiAlwaysLookup = DB_JNDI_ALWAYS_LOOKUP org.quartz.dataSource.myXADS.java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory org.quartz.dataSource.myXADS.java.naming.provider.url = t3://localhost:7020 org.quartz.dataSource.myXADS.java.naming.security.principal = weblogic org.quartz.dataSource.myXADS.java.naming.security.credentials = weblogic

      重寫?quartz?的?QuartzJobBean?類

      原因是在使用?quartz+spring?把?quartz?的?task?實(shí)例化進(jìn)入數(shù)據(jù)庫(kù)時(shí),會(huì)產(chǎn)生:?serializable?的錯(cuò)誤,原因在于:

      execute

      這個(gè)?MethodInvokingJobDetailFactoryBean?類中的?methodInvoking?方法,是不支持序列化的,因此在把QUARTZ?的?TASK?序列化進(jìn)入數(shù)據(jù)庫(kù)時(shí)就會(huì)拋錯(cuò)。網(wǎng)上有說(shuō)把?SPRING?源碼拿來(lái),修改一下這個(gè)方案,然后再打包成?SPRING.jar?發(fā)布,這些都是不好的方法,是不安全的。

      必須根據(jù)?QuartzJobBean?來(lái)重寫一個(gè)自己的類,然后使用?SPRING?把這個(gè)重寫的類(我們就名命它為:MyDetailQuartzJobBean?)注入?appContext?中后,再使用?AOP?技術(shù)反射出原有的?quartzJobx(?就是開發(fā)人員原來(lái)已經(jīng)做好的用于執(zhí)行?QUARTZ?的?JOB?的執(zhí)行類?)?。

      下面來(lái)看?MyDetailQuartzJobBean?類:

      public class MyDetailQuartzJobBean extends QuartzJobBean { protected final Log logger = LogFactory.getLog(getClass()); private String targetObject; private String targetMethod; private ApplicationContext ctx; protected void executeInternal(JobExecutionContext context) throws JobExecutionException { try { logger.info("execute [" + targetObject + "] at once>>>>>>"); Object otargetObject = ctx.getBean(targetObject); Method m = null; try { m = otargetObject.getClass().getMethod(targetMethod, new Class[] {}); m.invoke(otargetObject, new Object[] {}); } catch (SecurityException e) { logger.error(e); } catch (NoSuchMethodException e) { logger.error(e); } } catch (Exception e) { throw new JobExecutionException(e); } } public void setApplicationContext(ApplicationContext applicationContext){ this.ctx=applicationContext; } public void setTargetObject(String targetObject) { this.targetObject = targetObject; } public void setTargetMethod(String targetMethod) { this.targetMethod = targetMethod; } }

      再來(lái)看完整的?quartz.xml?(注意紅色加粗部分尤為重要):

      com.testcompany.framework.quartz. MyDetailQuartzJobBean 0/5 * * * * ?

      下載最新的?quartz1.8?版,把?quartz-all-1.8.4.jar, quartz-oracle-1.8.4.jar,quartz-weblogic-1.8.4.jar?這三個(gè)包放到?web-inf/lib?目錄下,布署。

      測(cè)試:

      幾個(gè)節(jié)點(diǎn)都帶有?quartz?任務(wù),此時(shí)只有一臺(tái)?quartz?在運(yùn)行,另幾個(gè)節(jié)點(diǎn)上的?quartz?沒(méi)有運(yùn)行。

      此時(shí)手動(dòng)?shutdown?那臺(tái)運(yùn)行?QUARTZ?(在程序里加?system.out.println(“execute once…”),?運(yùn)行?quartz的那個(gè)節(jié)點(diǎn)在后臺(tái)會(huì)打印?execute once?)的節(jié)點(diǎn),過(guò)了?7?秒左右,另一個(gè)節(jié)點(diǎn)的?quartz?自動(dòng)監(jiān)測(cè)到了集群中運(yùn)行著的?quartz?的?instance?已經(jīng)?shutdown?,因此?quartz?集群會(huì)自動(dòng)把任一臺(tái)可用的?APP?上啟動(dòng)起一個(gè)?quartz job?的任務(wù)。

      quartz在集群環(huán)境下的最終解決方案

      自此,?QUARTZ?使用?HA?策略的集群大功告成,不用改原有代碼,配置一下我們就可作到?QUARTZ?的集群與自動(dòng)錯(cuò)誤冗余。

      Spring 數(shù)據(jù)庫(kù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Excel表格怎么批量去除單元格內(nèi)最后一個(gè)字
      下一篇:小白爬蟲第四彈之爬蟲快跑(多進(jìn)程 + 多線程)
      相關(guān)文章
      亚洲精品99久久久久中文字幕| 亚洲一区AV无码少妇电影☆| 亚洲第一福利网站在线观看| 亚洲一级免费毛片| 亚洲国产精品成人久久| 亚洲一区二区三区香蕉| 久久精品夜色噜噜亚洲A∨| 亚洲精品乱码久久久久久蜜桃| 亚洲av无码不卡私人影院| 国产亚洲视频在线播放大全| 亚洲a∨国产av综合av下载| 亚洲AV女人18毛片水真多| 亚洲Aⅴ在线无码播放毛片一线天| 亚洲AV成人无码网天堂| 欧美亚洲精品一区二区| 自拍偷自拍亚洲精品播放| 成人亚洲综合天堂| 亚洲国产高清在线一区二区三区| 亚洲AV无码乱码在线观看性色扶| 另类专区另类专区亚洲| 亚洲天堂在线视频| 亚洲色无码专区在线观看| 亚洲色大成网站www永久一区| 国产精品亚洲аv无码播放| 亚洲va国产va天堂va久久| 亚洲精品高清久久| 91亚洲国产在人线播放午夜| 亚洲理论精品午夜电影| 亚洲综合久久一本伊伊区| 国产亚洲精品VA片在线播放| 亚洲风情亚Aⅴ在线发布| 亚洲Av无码乱码在线观看性色 | 亚洲成AV人在线观看网址| 亚洲一区二区三区国产精品| 亚洲人成色7777在线观看| 亚洲国产成人久久综合一| 亚洲毛片免费视频| 亚洲色中文字幕在线播放| 亚洲av无码成人精品区| 国产亚洲精品美女久久久| 亚洲黄色片免费看|