在我們開(kāi)發(fā)的一個(gè)系統(tǒng)中,有定時(shí)任務(wù),自然就想到了Quartz,由于框架采用的Spring,Quartz跟Spring的集成也非常簡(jiǎn)單,所以就把Quartz配置到框架中,當(dāng)系統(tǒng)啟動(dòng)后,定時(shí)任務(wù)也就自動(dòng)啟動(dòng)。在開(kāi)發(fā)的過(guò)程中一直沒(méi)有發(fā)現(xiàn)問(wèn)題,但是最后上線的時(shí)候,采用的是weblogic cluster,啟動(dòng)了4個(gè)節(jié)點(diǎn),發(fā)現(xiàn)有的定時(shí)任務(wù)執(zhí)行了不止一次,才恍然大悟,4個(gè)節(jié)點(diǎn)啟動(dòng)了4個(gè)應(yīng)用,也就啟動(dòng)了4個(gè)定時(shí)任務(wù),所以在同一個(gè)時(shí)間定時(shí)任務(wù)執(zhí)行了不止一次。去網(wǎng)上搜索,發(fā)現(xiàn)Quartz也支持cluster,但是我覺(jué)得就我們的系統(tǒng)而言,沒(méi)有必要采用cluster的定時(shí)任務(wù),也許是比較懶吧,就想讓定時(shí)任務(wù)只執(zhí)行一次。在網(wǎng)上搜到了robbin的一篇文章(http://robbin.iteye.com/blog/40989 ),發(fā)現(xiàn)把quartz集中到webapp當(dāng)中還是有一定的風(fēng)險(xiǎn),同時(shí)同一個(gè)時(shí)間點(diǎn)執(zhí)行也不止一次。Robbin的解決辦法就是自己?jiǎn)为?dú)啟動(dòng)一個(gè)Job Server,來(lái)quartz跑job,不要部署在web容器中。
我也比較同意這個(gè)辦法。鑒于時(shí)間比較緊,就想有沒(méi)有比較方便的方法。其實(shí)把原來(lái)的webapp當(dāng)做一個(gè)quartz的容器就可以了。可以自己寫(xiě)一個(gè)線程來(lái)跑應(yīng)用,再寫(xiě)一個(gè)command啟動(dòng)這個(gè)線程就可以了。線程類(lèi)很簡(jiǎn)單,如下:
public class StartServer { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( new String[] { "/spring/context-annotation.xml","/spring/context-transaction.xml", "/spring/context-hibernate.xml", "/spring/context-quartz.xml"}); System.out.println("start server...."); while (true) { try { Thread.sleep(900); } catch (InterruptedException ex) { } } }; } |
去掉了系統(tǒng)的controller配置servlet.xml,運(yùn)行這個(gè)類(lèi)就可以了。
在web-inf目錄下寫(xiě)一個(gè)command來(lái)啟動(dòng)這個(gè)java類(lèi):
setlocal ENABLEDELAYEDEXPANSION if defined CLASSPATH (set CLASSPATH=%CLASSPATH%;.) else (set CLASSPATH=.) FOR /R .\lib %%G IN (*.jar) DO set CLASSPATH=!CLASSPATH!;%%G Echo The Classpath definition is==== %CLASSPATH% set CLASSPATH=./classes;%CLASSPATH% java com.company.job.StartServer |
這個(gè)command需要把需要的jar(web-inf/lib中)包都放到classpath中。
每次啟動(dòng)的時(shí)候執(zhí)行這個(gè)command就可以了。跟原來(lái)的應(yīng)用分開(kāi)了,調(diào)試起定時(shí)任務(wù)也不用影響到原來(lái)的應(yīng)用,還是比較方便的。部署的時(shí)候原樣拷貝一份,然后執(zhí)行這個(gè)command就好了,部署起來(lái)也比較方便。