菜園子

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            7 Posts :: 1 Stories :: 31 Comments :: 0 Trackbacks

          在我們開發(fā)的一個系統(tǒng)中,有定時任務(wù),自然就想到了Quartz,由于框架采用的Spring,Quartz跟Spring的集成也非常簡單,所以就把Quartz配置到框架中,當(dāng)系統(tǒng)啟動后,定時任務(wù)也就自動啟動。在開發(fā)的過程中一直沒有發(fā)現(xiàn)問題,但是最后上線的時候,采用的是weblogic cluster,啟動了4個節(jié)點,發(fā)現(xiàn)有的定時任務(wù)執(zhí)行了不止一次,才恍然大悟,4個節(jié)點啟動了4個應(yīng)用,也就啟動了4個定時任務(wù),所以在同一個時間定時任務(wù)執(zhí)行了不止一次。去網(wǎng)上搜索,發(fā)現(xiàn)Quartz也支持cluster,但是我覺得就我們的系統(tǒng)而言,沒有必要采用cluster的定時任務(wù),也許是比較懶吧,就想讓定時任務(wù)只執(zhí)行一次。在網(wǎng)上搜到了robbin的一篇文章(http://robbin.iteye.com/blog/40989 ),發(fā)現(xiàn)把quartz集中到webapp當(dāng)中還是有一定的風(fēng)險,同時同一個時間點執(zhí)行也不止一次。Robbin的解決辦法就是自己單獨啟動一個Job Server,來quartz跑job,不要部署在web容器中。 

          我也比較同意這個辦法。鑒于時間比較緊,就想有沒有比較方便的方法。其實把原來的webapp當(dāng)做一個quartz的容器就可以了。可以自己寫一個線程來跑應(yīng)用,再寫一個command啟動這個線程就可以了。線程類很簡單,如下:

          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,運行這個類就可以了。

          在web-inf目錄下寫一個command來啟動這個java類:

          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

          這個command需要把需要的jar(web-inf/lib中)包都放到classpath中。

          每次啟動的時候執(zhí)行這個command就可以了。跟原來的應(yīng)用分開了,調(diào)試起定時任務(wù)也不用影響到原來的應(yīng)用,還是比較方便的。部署的時候原樣拷貝一份,然后執(zhí)行這個command就好了,部署起來也比較方便。

           



          QQ:24889356
          posted on 2011-09-13 12:53 GhostZhang 閱讀(2662) 評論(3)  編輯  收藏

          Feedback

          # re: 一次定時任務(wù) 2011-09-14 08:55 tb
          恩 不錯   回復(fù)  更多評論
            

          # re: 一次定時任務(wù) 2011-09-15 18:19 Mister4
          可以根據(jù)服務(wù)器的iP做個判斷  回復(fù)  更多評論
            

          # re: 一次定時任務(wù)[未登錄] 2011-09-30 15:57 BucketLi
          這個簡單處理方式有很多. 數(shù)據(jù)庫搞張任務(wù)表,放一條記錄,每個節(jié)點先取這條記錄(任務(wù)狀態(tài)是可執(zhí)行),然后再通過update將value+1并且更新狀態(tài),帶上先前查詢出來的value作為查詢條件,這樣相當(dāng)于加了一把樂觀鎖,因為數(shù)據(jù)庫底層是原子的,所以只有一臺機器會更新成功. 這樣就達(dá)到目的了. 還有稍微復(fù)雜點的是通過zk來維持一把任務(wù)鎖,這樣執(zhí)行任務(wù)的只有一臺機器,掛掉后另外一臺機器搶到鎖開始做事情. 當(dāng)然還有其他方法  回復(fù)  更多評論
            


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 乐都县| 嘉黎县| 如东县| 仁布县| 扶沟县| 大石桥市| 黄平县| 西平县| 拜城县| 逊克县| 治县。| 浦北县| 南郑县| 柯坪县| 孟村| 峨眉山市| 宜川县| 松潘县| 神农架林区| 南澳县| 安福县| 义乌市| 肥乡县| 贺兰县| 岳阳市| 双鸭山市| 阿克陶县| 鹤峰县| 海门市| 双柏县| 泰兴市| 玛纳斯县| 弥渡县| 海兴县| 桂东县| 马尔康县| 高邑县| 洛扎县| 元谋县| 津南区| 白城市|