<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kingpub

    海內存知己,博客若比鄰

     

    Quartz從入門到進階

    Quartz從入門到進階

    作者:Cavaness

    譯者:David_w_johnson


    版權聲明:任何獲得Matrix授權的網站,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
    作者:Cavaness;David_w_johnson
    原文地址:http://www.onjava.com/pub/a/onjava/2005/09/28/what-is-quartz.html
    中文地址:http://www.matrix.org.cn/resource/article/43/43968_Quartz.html
    關鍵詞: Quartz


    Quartz

    Quartz 是一個開源的作業調度框架,它完全由java寫成,并設計用于J2SE和J2EE應用中。它提供了巨大的靈活性而不犧牲簡單性。你能夠用它來為執行一個作業而創建簡單的或復雜的調度。它有很多特征,如:數據庫支持,集群,插件,EJB作業預構建,JavaMail及其它,支持cron-like表達式等等。

    本文內容
    1.????????Quartz讓任務調度簡單
    2.????????Quartz的發展史
    3.????????上手Quartz
    4.????????Quartz內部架構
    5.????????作業
    6.????????作業管理和存儲
    7.????????有效作業存儲
    8.????????作業和觸發器
    9.????????調度一個作業
    10.????????用調度器(Scheduler)調用你的作業
    11.????????編程調度同聲明性調度
    12.????????有狀態和無狀態作業
    13.????????Quartz框架的其他特征
    14.????????Quartz下一步計劃
    15.????????了解更多Quartz特征


    你曾經需要應用執行一個任務嗎?這個任務每天或每周星期二晚上11:30,或許僅僅每個月的最后一天執行。一個自動執行而無須干預的任務在執行過程中如果發生一個嚴重錯誤,應用能夠知到其執行失敗并嘗試重新執行嗎?你和你的團隊是用java編程嗎?如果這些問題中任何一個你回答是,那么你應該使用 Quartz調度器。

    旁注:Matrix目前就大量使用到了Quartz。比如,排名統計功能的實現,在Jmatrix里通過Quartz定義了一個定時調度作業,在每天凌晨一點,作業開始工作,重新統計大家的Karma和排名等。
    還有,RSS文件的生成,也是通過Quartz定義作業,每隔半個小時生成一次RSS XML文件。
    所以Quartz使用的地方很多,本文無疑是一篇很好的入門和進階的文章,在此,感謝David w Johnson的努力!


    Quartz讓作業調度簡單

    Quartz 是一個完全由java編寫的開源作業調度框架。不要讓作業調度這個術語嚇著你。盡管Quartz框架整合了許多額外功能,但就其簡易形式看,你會發現它易用得簡直讓人受不了!。簡單地創建一個實現org.quartz.Job接口的java類。Job接口包含唯一的方法:

    public void execute(JobExecutionContext context) 
    ???? throws JobExecutionException;


    在你的Job接口實現類里面,添加一些邏輯到execute()方法。一旦你配置好Job實現類并設定好調度時間表,Quartz將密切注意剩余時間。當調度程序確定該是通知你的作業的時候,Quartz框架將調用你Job實現類(作業類)上的execute()方法并允許做它該做的事情。無需報告任何東西給調度器或調用任何特定的東西。僅僅執行任務和結束任務即可。如果配置你的作業在隨后再次被調用,Quartz框架將在恰當的時間再次調用它。

    如果你使用了其它流行的開源框架象struts,你會對Quartz的設計和部件感到舒適。雖然兩個開源工程是解決完全不同的問題,還是有很多相似的之處,就是開源軟件用戶每天感覺很舒適。Quartz能用在單機J2SE應用中,作為一個RMI服務器,也可以用在web應用中,甚至也可以用在J2EE應用服務器中。

    Quartz的發展史

    盡管Quartz今年開始受到人們注意,但還是暫時流行。Quartz由James House創建并最初于2001年春天被加入sourceforge工程。接下來的幾年里,有許多新特征和版本出現,但是直到項目遷移到新的站點并成為 OpenSymphony項目家族的一員,才開始真正啟動并受到應有的關注。
    James House仍然和幾個協助他的業余開發者參與大量開發工作。Quartz開發團隊今年能發布幾個新版本,包括當前正處在候選發布階段的1.5版。

    上手Quartz
    Quartz工程駐留在OpenSymphony站點上。在Quartz站點上可以找到許多有用的資源:JavaDocs,包含指南的文檔,CVS訪問,用戶和開發者論壇的連接,當然也有下載。
    從下載連接取得Quartz的發布版本,并且解壓到到本地目錄。這個下載文件包含了一個預先構建好的Quartz二進制文件(quartz.jar),你可以將它放進自己的應用中。Quartz框架只需要少數的第三方庫,并且這些三方庫是必需的,你很可能已經在使用這些庫了。

    你要把 Quartz的安裝目錄的<quartz- install>/lib/core 和 <quartz-install>/lib/optional目錄中的第三方庫加進你自己的工程中。大多數第三方庫是我們所熟知和喜歡的標準 Jakarta Commons庫,像Commons Logging, Commons BeantUtils等等。
    ????
    quartz.properties文件
    Quartz 有一個叫做quartz.properties的配置文件,它允許你修改框架運行時環境。缺省是使用Quartz.jar里面的 quartz.properties文件。當然,你應該創建一個quartz.properties文件的副本并且把它放入你工程的classes目錄中以便類裝載器找到它。quartz.properties樣本文件如例1所示。

    例1.quartz.properties文件允許修改Quartz運行環境:

    #===============================================================
    # Configure Main Scheduler Properties??
    #===============================================================

    org.quartz.scheduler.instanceName = QuartzScheduler
    org.quartz.scheduler.instanceId = AUTO

    #===============================================================
    # Configure ThreadPool??
    #===============================================================

    org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
    org.quartz.threadPool.threadCount =??5
    org.quartz.threadPool.threadPriority = 5

    #===============================================================
    # Configure JobStore??
    #===============================================================

    org.quartz.jobStore.misfireThreshold = 60000
    org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore


    一旦將Quartz.jar文件和第三方庫加到自己的工程里面并且quartz.properties文件在工程的classes目錄中,就可以創建作業了。然而,在做這之前,我們暫且回避一下先簡短討論一下Quartz架構。

    Quartz內部架構
    在規模方面,Quartz跟大多數開源框架類似。大約有300個java類和接口,并被組織到12個包中。這可以和Apache Struts把大約325個類和接口以及組織到11個包中相比。盡管規模幾乎不會用來作為衡量框架質量的一個特性,但這里的關鍵是quarts內含很多功能,這些功能和特性集是否成為、或者應該成為評判一個開源或非開源框架質量的因素。

    Quartz調度器
    Quartz 框架的核心是調度器。調度器負責管理Quartz應用運行時環境。調度器不是靠自己做所有的工作,而是依賴框架內一些非常重要的部件。Quartz不僅僅是線程和線程管理。為確保可伸縮性,Quartz采用了基于多線程的架構。啟動時,框架初始化一套worker線程,這套線程被調度器用來執行預定的作業。這就是Quartz怎樣能并發運行多個作業的原理。Quartz依賴一套松耦合的線程池管理部件來管理線程環境。本片文障中,我們會多次提到線程池管理,但Quartz里面的每個對象是可配置的或者是可定制的。所以,例如,如果你想要插進自己線程池管理設施,我猜你一定能!

    作業
    用Quartz 的行話講,作業是一個執行任務的簡單java類。任務可以是任何java代碼。只需你實現org.quartz.Job接口并且在出現嚴重錯誤情況下拋出 JobExecutionException異常即可。Job接口包含唯一的一個方法execute(),作業從這里開始執行。一旦實現了Job接口和 execute()方法,當Quartz確定該是作業運行的時候,它將調用你的作業。Execute()方法內就完全是你要做的事情。下面有一些你要在作業里面做事情的例子:
    ·????????用JavaMail(或者用其他的像Commons Net一樣的郵件框架)發送郵件
    ·????????創建遠程接口并且調用在EJB上的方法
    ·????????獲取Hibernate Session,查詢和更新關系數據庫里的數據
    ·????????使用OSWorkflow并且從作業調用一個工作流
    ·????????使用FTP和到處移動文件
    ·????????調用Ant構建腳本開始預定構建

    這種可能性是無窮的,正事這種無限可能性使得框架功能如此強大。Quartz給你提供了一個機制來建立具有不同粒度的、可重復的調度表,于是,你只需創建一個java類,這個類被調用而執行任務。

    作業管理和存儲
    作業一旦被調度,調度器需要記住并且跟蹤作業和它們的執行次數。如果你的作業是30分鐘后或每30秒調用,這不是很有用。事實上,作業執行需要非常準確和即時調用在被調度作業上的execute()方法。Quartz通過一個稱之為作業存儲(JobStore)的概念來做作業存儲和管理。


    有效作業存儲

    Quartz 提供兩種基本作業存儲類型。第一種類型叫做RAMJobStore,它利用通常的內存來持久化調度程序信息。這種作業存儲類型最容易配置、構造和運行。對許多應用來說,這種作業存儲已經足夠了。然而,因為調度程序信息是存儲在被分配給JVM的內存里面,所以,當應用程序停止運行時,所有調度信息將被丟失。如果你需要在重新啟動之間持久化調度信息,則將需要第二種類型的作業存儲。

    第二種類型的作業存儲實際上提供兩種不同的實現,但兩種實現一般都稱為JDBC作業存儲。兩種JDBC作業存儲都需要JDBC驅動程序和后臺數據庫來持久化調度程序信息。這兩種類型的不同在于你是否想要控制數據庫事務或這釋放控制給應用服務器例如BEA's WebLogic或Jboss。(這類似于J2EE領域中,Bean管理的事務和和容器管理事務之間的區別)
    這兩種JDBC作業存儲是:

    ·????????JobStoreTX:當你想要控制事務或工作在非應用服務器環境中是使用
    ·????????JobStoreCMT:當你工作在應用服務器環境中和想要容器控制事務時使用。

    JDBC作業存儲為需要調度程序維護調度信息的用戶而設計。

    作業和觸發器

    Quartz 設計者做了一個設計選擇來從調度分離開作業。Quartz中的觸發器用來告訴調度程序作業什么時候觸發。框架提供了一把觸發器類型,但兩個最常用的是 SimpleTrigger和CronTrigger。SimpleTrigger為需要簡單打火調度而設計。典型地,如果你需要在給定的時間和重復次數或者兩次打火之間等待的秒數打火一個作業,那么SimpleTrigger適合你。另一方面,如果你有許多復雜的作業調度,那么或許需要 CronTrigger。

    CronTrigger是基于Calendar-like調度的。當你需要在除星期六和星期天外的每天上午10點半執行作業時,那么應該使用CronTrigger。正如它的名字所暗示的那樣,CronTrigger是基于Unix克隆表達式的。

    作為一個例子,下面的Quartz克隆表達式將在星期一到星期五的每天上午10點15分執行一個作業。
    0 15 10 ? * MON-FRI

    下面的表達式
    0 15 10 ? * 6L 2002-2005
    將在2002年到2005年的每個月的最后一個星期五上午10點15分執行作業。

    你不可能用SimpleTrigger來做這些事情。你可以用兩者之中的任何一個,但哪個跟合適則取決于你的調度需要。


    調度一個作業

    讓我們通過看一個例子來進入實際討論?,F假定你管理一個部門,無論何時候客戶在它的FTP服務器上存儲一個文件,都得用電子郵件通知它。我們的作業將用 FTP登陸到遠程服務器并下載所有找到的文件。然后,它將發送一封含有找到和下載的文件數量的電子郵件。這個作業很容易就幫助人們整天從手工執行這個任務中解脫出來,甚至連晚上都無須考慮。我們可以設置作業循環不斷地每60秒檢查一次,而且工作在7×24模式下。這就是Quartz框架完全的用途。

    首先創建一個Job類,將執行FTP和Email邏輯。下例展示了Quartz的Job類,它實現了org.quartz.Job接口。

    例2.從FTP站點下載文件和發送email的Quartz作業

    public class ScanFTPSiteJob implements Job {
    ????private static Log logger = LogFactory.getLog(ScanFTPSiteJob.class);

    ????/*
    ???? * Called the scheduler framework at the right time
    ???? */
    ????public void execute(JobExecutionContext context)
    ????????????throws JobExecutionException {

    ????????JobDataMap jobDataMap = context.getJobDataMap();

    ????????try {
    ????????????// Check the ftp site for files
    ????????????File[] files = JobUtil.checkForFiles(jobDataMap);

    ????????????JobUtil.sendEmail(jobDataMap, files);
    ????????} catch (Exception ex) {
    ????????????throw new JobExecutionException(ex.getMessage());
    ????????}
    ????}
    }


    我們故意讓ScanFTPSiteJob保持很簡單。我們為這個例子創建了一個叫做JobUtil的實用類。它不是Quartz的組成部分,但對構建各種作業能重用的實用程序庫來說是有意義的。我們可以輕易將那種代碼組織進作業類中,quarts 調度器一樣好用,因為我們一直在使用quarts,所以那些代碼可繼續重用。

    JobUtil.checkForFiles() and JobUtil.sendEmail()方法使用的參數是Quartz創建的JobDataMap的實例。實例為每個作業的執行而創建,它是向作業類傳遞配置參數的方法。
    這里并沒有展示JobUtil的實現,但我們能用Jakarta上的Commons Net輕易地實現FTP和Email功能。

    用調度器調用作業

    首先創建一個作業,但為使作業能被調度器調用,你得向調度程序說明你的作業的調用時間和頻率。這個事情由與作業相關的觸發器來完成。因為我們僅僅對大約每60秒循環調用作業感興趣,所以打算使用SimpleTrigger。

    作業和觸發器通過Quartz調度器接口而被調度。我們需要從調度器工廠類取得一個調度器的實例。最容易的辦法是調用StdSchedulerFactory這個類上的靜態方法getDefaultScheduler()。
    使用Quartz框架,你需要調用start()方法來啟動調度器。例3的代碼遵循了大多數Quartz應用的一般模式:創建一個或多個作業,創建和設置觸發器,用調度器調度作業和觸發器,啟動調度器。

    例3.Quartz作業通過Quartz調度器而被調度

    public class MyQuartzServer {

    ????public static void main(String[] args) {
    ????????MyQuartzServer server = new MyQuartzServer();

    ????????try {
    ????????????server.startScheduler();
    ????????} catch (SchedulerException ex) {
    ????????????ex.printStackTrace();
    ????????}
    ????}

    ????protected void startScheduler() throws SchedulerException {

    ????????// Use the factory to create a Scheduler instance
    ????????Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

    ????????// JobDetail holds the definition for Jobs
    ????????JobDetail jobDetail =
    new JobDetail("ScanFTPJob", Scheduler.DEFAULT_GROUP,
    ????????????????ScanFTPSiteJob.class);

    // Store job parameters to be used within execute()
    jobDetail.getJobDataMap().put(
    "FTP_HOST",
    "\\home\\cavaness\\inbound");

    ????????// Other neccessary Job parameters here

    ????????// Create a Trigger that fires every 60 seconds
    ????????Trigger trigger = TriggerUtils.makeSecondlyTrigger(60);
    ????????
    ????????// Setup the Job and Trigger with the Scheduler
    ????????scheduler.scheduleJob(jobDetail, trigger );
    ????????
    ????????// Start the Scheduler running
    ????????scheduler.start();
    ????}
    }



    編程調度同聲明性調度

    例3中,我們通過編程的方法調度我們的ScanFTPSiteJob作業。就是說,我們用java代碼來設置作業和觸發器。Quartz框架也支持在xml文件里面申明性的設置作業調度。申明性方法允許我們更快速地修改哪個作業什么時候被執行。

    Quartz 框架有一個插件,這個插件負責讀取xml配置文件。xml配置文件包含了關于啟動Quartz應用的作業和觸發器信息。所有xml文件中的作業連同相關的觸發器都被加進調度器。你仍然需要編寫作業類,但配置那些作業類的調度器則非常動態化。例4展示了一個用申明性方式執行與例3代碼相同的邏輯的xml配置文件。

    例4.能使用xml文件調度的作業

    <?xml version='1.0' encoding='utf-8'?>
    <quartz>
    ????<job>
    ????????<job-detail>
    ????????????<name>ScanFTPSiteJob</name>
    ????????????<group>DEFAULT</group>
    ????????????<description>
    ????????????????A job that scans an ftp site for files
    ????????????</description>
    ????????????<job-class>ScanFTPSiteJob</job-class>

    ????????????<job-data-map allows-transient-data="true">
    ????????????????<entry>
    ????????????????????<key>FTP_HOST</key>
    ????????????????????<value>\home\cavaness\inbound</value>
    ????????????????</entry>
    ????????????????
    ????????????????<!--??Other neccessary Job parameters here -->

    ????????????</job-data-map>
    ????????</job-detail>

    ????????<trigger>
    ????????????<simple>
    ????????????????<name>ScanFTPSiteJobTrigger</name>
    ????????????????<group>DEFAULT</group>
    ????????????????<job-name>ScanFTPSiteJob</job-name>
    ????????????????<job-group>DEFAULT</job-group>
    ????????????????<start-time>2005-09-11 6:10:00 PM</start-time>
    ????????????????<!-- repeat indefinitely every 60 seconds -->
    ????????????????<repeat-count>-1</repeat-count>
    ????????????????<repeat-interval>60000</repeat-interval>
    ????????????</simple>
    ????????</trigger>

    ????</job>
    </quartz>


    你可以將xml文件中的元素跟例3代碼作個比較,它們從概念上來看是相同的。使用例4式的申明性方法的好處是維護變得極其簡單,只需改變xml配置文件和重新啟動Quartz應用即可。無須修改代碼,無須重新編譯,無須重新部署。

    有狀態和無狀態作業

    在本文中你所看到的作業到是無狀態的。這意味著在兩次作業執行之間,不會去維護作業執行時JobDataMap的狀態改變。如果你需要能增、刪,改JobDataMap的值,而且能讓作業在下次執行時能看到這個狀態改變,則需要用Quartz有狀態作業。
    如果你是一個有經驗的EJB開發者的話,深信你會立即退縮,因為有狀態帶有負面含義。這主要是由于EJB帶來的伸縮性問題。Quartz有狀態作業實現了 org.quartz.StatefulJob接口。無狀態和有狀態作業的關鍵不同是有狀態作業在每次執行時只有一個實例。大多數情況下,有狀態的作業不回帶來大的問題。然而,如果你有一個需要頻繁執行的作業或者需要很長時間才能完成的作業,那么有狀態作業可能給你帶來伸縮性問題。

    Quartz框架的其他特征

    Quartz框架有一個豐富的特征集。事實上,quarts有太多特性以致不能在一種情況中全部領會,下面列出了一些有意思的特征,但沒時間在此詳細討論。

    監聽器和插件

    每個人都喜歡監聽和插件。今天,幾乎下載任何開源框架,你必定會發現支持這兩個概念。監聽是你創建的java類,當關鍵事件發生時會收到框架的回調。例如,當一個作業被調度、沒有調度或觸發器終止和不再打火時,這些都可以通過設置來來通知你的監聽器。Quartz框架包含了調度器監聽、作業和觸發器監聽。你可以配置作業和觸發器監聽為全局監聽或者是特定于作業和觸發器的監聽。

    一旦你的一個具體監聽被調用,你就能使用這個技術來做一些你想要在監聽類里面做的事情。例如,你如果想要在每次作業完成時發送一個電子郵件,你可以將這個邏輯寫進作業里面,也可以JobListener里面。寫進 JobListener的方式強制使用松耦合有利于設計上做到更好。

    Quartz插件是一個新的功能特性,無須修改Quartz源碼便可被創建和添加進Quartz框架。他為想要擴展Quartz框架又沒有時間提交改變給Quartz開發團隊和等待新版本的開發人員而設計。如果你熟悉 Struts插件的話,那么完全可以理解Quartz插件的使用。

    與其Quartz提供一個不能滿足你需要的有限擴展點,還不如通過使用插件來擁有可修整的擴展點。

    集群Quartz應用
    Quartz應用能被集群,是水平集群還是垂直集群取決于你自己的需要。集群提供以下好處:
    ·????????伸縮性
    ·????????搞可用性
    ·????????負載均衡
    目前,Quartz只能借助關系數據庫和JDBC作業存儲支持集群。將來的版本這個制約將消失并且用RAMJobStore集群將是可能的而且將不需要數據庫的支持。

    Quartz web應用
    使用框架幾個星期或幾個月后,Quartz用戶所顯示的需求之一是需要集成Quartz到圖形用戶界面中。目前Quartz框架已經有一些工具允許你使用 Java servlet來初始化和啟動Quartz。一旦你可以訪問調度器實例,你就可以把它存儲在web容器的servlet上下文中(ServletContext中)并且可以通過調度器接口管理調度環境。

    幸運的是一些開發者已正影響著單機Quartz web應用,它用來更好地管理調度器環境。構建在若干個流行開源框架如Struts和Spring之上的圖形用戶界面支持很多功能,這些功能都被包裝進一個簡單接口。GUI的一個畫面如圖1所示:


    image
    圖1.Quartz Web應用允許比較容易地管理Quartz環境。

    Quartz的下一步計劃

    Quartz是一個活動中的工程。Quartz開發團隊明確表示不會停留在已有的榮譽上。Quartz下一個主要版本已經在啟動中。你可以在OpenSymphony的 wiki上體驗一下Quartz 2.0的設計和特征。
    總之,Quartz用戶每天都自由地添加特性建議和設計創意以便能被核心框架考慮(看重)。

    了解更多Quartz特征

    當你開始使用Quartz框架的更多特性時,User and Developer Forum論壇變成一個回答問題和跟其他Quartz用戶溝通的極其有用的資源。經常去逛逛這個論壇時很有好處的,你也可以依靠James House來共享與你的需要相關的知識和意見。

    這個論壇時免費的,你不必登陸便可以查找和查看歸檔文件。然而,如果你覺得這個論壇比較好而且需要向某人回復問題時,你必須得申請一個免費帳號并用該帳號登陸。

    資源
    ·onjava.com:onjava.com
    ·Matrix-Java開發者社區:http://www.matrix.org.cn/

    Chuck Cavaness畢業于Georgia Tech并獲得計算機科學與技術學位。他在健康,銀行,B2B領域開發過基于java的企業系統。同時也是O'Reilly出版的兩本書 Programming Jakarta Struts 和 Jakarta Struts Pocket Reference的作者。

    posted on 2006-06-05 12:07 xiaofeng 閱讀(117) 評論(0)  編輯  收藏


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


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产成人精品免费视频大全| 久久精品免费一区二区喷潮| 亚洲精品成a人在线观看| 99亚洲精品卡2卡三卡4卡2卡| 成年女人喷潮毛片免费播放| 四虎永久成人免费| 亚洲人成在线观看| 日本免费大黄在线观看| 久久亚洲日韩看片无码| 久久精品国产亚洲av瑜伽| 免费无码又爽又高潮视频| 黄床大片30分钟免费看 | 成年人网站免费视频| 亚洲国产成人五月综合网| 亚洲天堂一区二区三区四区| 一级毛片aa高清免费观看| AV免费网址在线观看| 香蕉视频亚洲一级| 亚洲午夜久久久久久久久久| 日日麻批免费40分钟无码| 亚洲不卡中文字幕| 国产一级一片免费播放| 你是我的城池营垒免费看| 亚洲码在线中文在线观看| 波多野结衣免费一区视频| 免费国产小视频在线观看| 又长又大又粗又硬3p免费视频| 亚洲AV无码乱码在线观看裸奔| 一区免费在线观看| 亚洲成在人天堂在线| 免费人成视频在线| 一级有奶水毛片免费看| 亚洲色图在线播放| 国产免费看插插插视频| 国产一区二区三区免费观看在线| 亚洲狠狠狠一区二区三区| 免费一看一级毛片人| 午夜视频在线免费观看| 亚洲欧美成aⅴ人在线观看| 国产亚洲精AA在线观看SEE| 无码少妇一区二区浪潮免费|