偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

基于Quartz開發(fā)企業(yè)級任務(wù)調(diào)度應(yīng)用

開發(fā) 后端
Quartz 是 OpenSymphony 開源組織在任務(wù)調(diào)度領(lǐng)域的一個開源項目,完全基于 Java 實現(xiàn)。作為一個優(yōu)秀的開源調(diào)度框架,Quartz 具有功能強(qiáng)大,應(yīng)用靈活,易于集成的特點(diǎn)。本文剖析了 Quartz 框架內(nèi)部的基本實現(xiàn)原理,通過一些具體實例描述了應(yīng)用 Quartz 開發(fā)應(yīng)用程序的基本方法,并對企業(yè)應(yīng)用中常見的問題及解決方案進(jìn)行了討論。

簡介: Quartz 是 OpenSymphony 開源組織在任務(wù)調(diào)度領(lǐng)域的一個開源項目,完全基于 Java 實現(xiàn)。作為一個優(yōu)秀的開源調(diào)度框架,Quartz 具有功能強(qiáng)大,應(yīng)用靈活,易于集成的特點(diǎn)。本文剖析了 Quartz 框架內(nèi)部的基本實現(xiàn)原理,通過一些具體實例描述了應(yīng)用 Quartz 開發(fā)應(yīng)用程序的基本方法,并對企業(yè)應(yīng)用中常見的問題及解決方案進(jìn)行了討論。

Quartz 基本概念及原理

Quartz Scheduler 開源框架

Quartz 是 OpenSymphony 開源組織在任務(wù)調(diào)度領(lǐng)域的一個開源項目,完全基于 Java 實現(xiàn)。該項目于 2009 年被 Terracotta 收購,目前是 Terracotta 旗下的一個項目。讀者可以到 http://www.quartz-scheduler.org/站點(diǎn)下載 Quartz 的發(fā)布版本及其源代碼。筆者在產(chǎn)品開發(fā)中使用的是版本 1.8.4,因此本文內(nèi)容基于該版本。本文不僅介紹如何應(yīng)用 Quartz 進(jìn)行開發(fā),也對其內(nèi)部實現(xiàn)原理作一定講解。

作為一個優(yōu)秀的開源調(diào)度框架,Quartz 具有以下特點(diǎn):

強(qiáng)大的調(diào)度功能,例如支持豐富多樣的調(diào)度方法,可以滿足各種常規(guī)及特殊需求;

靈活的應(yīng)用方式,例如支持任務(wù)和調(diào)度的多種組合方式,支持調(diào)度數(shù)據(jù)的多種存儲方式;

分布式和集群能力,Terracotta 收購后在原來功能基礎(chǔ)上作了進(jìn)一步提升。本文暫不討論該部分內(nèi)容

另外,作為 Spring 默認(rèn)的調(diào)度框架,Quartz 很容易與 Spring 集成實現(xiàn)靈活可配置的調(diào)度功能。

下面是本文中用到的一些專用詞匯,在此聲明:

scheduler:任務(wù)調(diào)度器 trigger:觸發(fā)器,用于定義任務(wù)調(diào)度時間規(guī)則 job:任務(wù),即被調(diào)度的任務(wù) misfire:錯過的,指本來應(yīng)該被執(zhí)行但實際沒有被執(zhí)行的任務(wù)調(diào)度

Quartz 任務(wù)調(diào)度的基本實現(xiàn)原理

核心元素

Quartz 任務(wù)調(diào)度的核心元素是 scheduler, trigger 和 job,其中 trigger 和 job 是任務(wù)調(diào)度的元數(shù)據(jù), scheduler 是實際執(zhí)行調(diào)度的控制器。

在 Quartz 中,trigger 是用于定義調(diào)度時間的元素,即按照什么時間規(guī)則去執(zhí)行任務(wù)。Quartz 中主要提供了四種類型的 trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,和 NthIncludedDayTrigger。這四種 trigger 可以滿足企業(yè)應(yīng)用中的絕大部分需求。我們將在企業(yè)應(yīng)用一節(jié)中進(jìn)一步討論四種 trigger 的功能。

在 Quartz 中,job 用于表示被調(diào)度的任務(wù)。主要有兩種類型的 job:無狀態(tài)的(stateless)和有狀態(tài)的(stateful)。對于同一個 trigger 來說,有狀態(tài)的 job 不能被并行執(zhí)行,只有上一次觸發(fā)的任務(wù)被執(zhí)行完之后,才能觸發(fā)下一次執(zhí)行。Job 主要有兩種屬性:volatility 和 durability,其中 volatility 表示任務(wù)是否被持久化到數(shù)據(jù)庫存儲,而 durability 表示在沒有 trigger 關(guān)聯(lián)的時候任務(wù)是否被保留。兩者都是在值為 true 的時候任務(wù)被持久化或保留。一個 job 可以被多個 trigger 關(guān)聯(lián),但是一個 trigger 只能關(guān)聯(lián)一個 job。

在 Quartz 中, scheduler 由 scheduler 工廠創(chuàng)建:DirectSchedulerFactory 或者 StdSchedulerFactory。 第二種工廠 StdSchedulerFactory 使用較多,因為 DirectSchedulerFactory 使用起來不夠方便,需要作許多詳細(xì)的手工編碼設(shè)置。 Scheduler 主要有三種:RemoteMBeanScheduler, RemoteScheduler 和 StdScheduler。本文以最常用的 StdScheduler 為例講解。這也是筆者在項目中所使用的 scheduler 類。

Quartz 核心元素之間的關(guān)系如下圖所示:

圖 1. Quartz 核心元素關(guān)系圖

圖 1. Quartz 核心元素關(guān)系圖 
 

線程視圖

在 Quartz 中,有兩類線程,Scheduler 調(diào)度線程和任務(wù)執(zhí)行線程,其中任務(wù)執(zhí)行線程通常使用一個線程池維護(hù)一組線程。

圖 2. Quartz 線程視圖

圖 2. Quartz 線程視圖 
 

Scheduler 調(diào)度線程主要有兩個: 執(zhí)行常規(guī)調(diào)度的線程,和執(zhí)行 misfired trigger 的線程。常規(guī)調(diào)度線程輪詢存儲的所有 trigger,如果有需要觸發(fā)的 trigger,即到達(dá)了下一次觸發(fā)的時間,則從任務(wù)執(zhí)行線程池獲取一個空閑線程,執(zhí)行與該 trigger 關(guān)聯(lián)的任務(wù)。Misfire 線程是掃描所有的 trigger,查看是否有 misfired trigger,如果有的話根據(jù) misfire 的策略分別處理。下圖描述了這兩個線程的基本流程:

圖 3. Quartz 調(diào)度線程流程圖

圖 3. Quartz 調(diào)度線程流程圖 
 

關(guān)于 misfired trigger,我們在企業(yè)應(yīng)用一節(jié)中將進(jìn)一步描述。

#p#

數(shù)據(jù)存儲

Quartz 中的 trigger 和 job 需要存儲下來才能被使用。Quartz 中有兩種存儲方式:RAMJobStore, JobStoreSupport,其中 RAMJobStore 是將 trigger 和 job 存儲在內(nèi)存中,而 JobStoreSupport 是基于 jdbc 將 trigger 和 job 存儲到數(shù)據(jù)庫中。RAMJobStore 的存取速度非??欤怯捎谄湓谙到y(tǒng)被停止后所有的數(shù)據(jù)都會丟失,所以在通常應(yīng)用中,都是使用 JobStoreSupport。

在 Quartz 中,JobStoreSupport 使用一個驅(qū)動代理來操作 trigger 和 job 的數(shù)據(jù)存儲:StdJDBCDelegate。StdJDBCDelegate 實現(xiàn)了大部分基于標(biāo)準(zhǔn) JDBC 的功能接口,但是對于各種數(shù)據(jù)庫來說,需要根據(jù)其具體實現(xiàn)的特點(diǎn)做某些特殊處理,因此各種數(shù)據(jù)庫需要擴(kuò)展 StdJDBCDelegate 以實現(xiàn)這些特殊處理。Quartz 已經(jīng)自帶了一些數(shù)據(jù)庫的擴(kuò)展實現(xiàn),可以直接使用,如下圖所示:

圖 4. Quartz 數(shù)據(jù)庫驅(qū)動代理

圖 4. Quartz 數(shù)據(jù)庫驅(qū)動代理
 

作為嵌入式數(shù)據(jù)庫的代表,Derby 近來非常流行。如果使用 Derby 數(shù)據(jù)庫,可以使用上圖中的 CloudscapeDelegate 作為 trigger 和 job 數(shù)據(jù)存儲的代理類。

 

基本開發(fā)流程及簡單實例

搭建開發(fā)環(huán)境

利用 Quartz 進(jìn)行開發(fā)相當(dāng)簡單,只需要將下載開發(fā)包中的 quartz-all-1.8.4.jar 加入到 classpath 即可。根據(jù)筆者的經(jīng)驗,對于任務(wù)調(diào)度功能比較復(fù)雜的企業(yè)級應(yīng)用來說,***在開發(fā)階段將 Quartz 的源代碼導(dǎo)入到開發(fā)環(huán)境中來。一方面可以通過閱讀源碼了解 Quartz 的實現(xiàn)機(jī)理,另一方面可以通過擴(kuò)展或修改 Quartz 的一些類來實現(xiàn)某些 Quartz 尚不提供的功能。

圖 5. Quartz 實例工程及源碼導(dǎo)入

圖 5. Quartz 實例工程及源碼導(dǎo)入 
 

上圖中左邊是源碼導(dǎo)入后的截圖,其中 org.quartz.* 即為 quartz 的源碼。導(dǎo)入源碼后可能會有一些編譯錯誤,通常出現(xiàn)在 org.quartz.ee.* 和 org.quartz.jobs.ee.* 包中。下載開發(fā)包中有一個 lib 目錄,讀者可以將該目錄下的 jar 文件加入到編譯環(huán)境。如果還有編譯錯誤,讀者可以參考上圖中右側(cè)的 jar 列表,到網(wǎng)上去搜索下載。

項目中 com.ibm.zxn.sample.quartz 是我們自己的類包,下面的實例中我們會用到它。

一個簡單實例

Quartz 開發(fā)包中有一個 examples 目錄,其中有 15 個基本實例。建議讀者閱讀并實踐這些例子。本文這里只列舉一個小的實例,介紹基本的開發(fā)方法。

準(zhǔn)備數(shù)據(jù)庫和 Quartz 用的數(shù)據(jù)表


圖 6. Quartz 數(shù)據(jù)表
圖 6. Quartz 數(shù)據(jù)表 
 

本文使用 IBM DB2 數(shù)據(jù)庫:將 jdbc 驅(qū)動程序 db2jcc.jar 加入到項目中;

在數(shù)據(jù)庫中創(chuàng)建一個新庫 QUARTZDB;

執(zhí)行 /quartz-1.8.4/docs/dbTables/tables_db2_v8.sql,創(chuàng)建數(shù)據(jù)表;表建好后如下所示:

準(zhǔn)備配置文件,加入到項目中

圖 7. 實例配置文件
圖 7. 實例配置文件 
 

通過實現(xiàn) job 接口定義我們自己的任務(wù)類,如下所示:

圖 8. 定義任務(wù)類
圖 8. 定義任務(wù)類 
 

然后,實現(xiàn)任務(wù)調(diào)度的主程序,如下所示:

本實例中,我們利用 DateIntervalTrigger 實現(xiàn)一個每兩分鐘執(zhí)行一次的任務(wù)調(diào)度。

圖 9. 實現(xiàn)主程序
圖 9. 實現(xiàn)主程序 
 

完成后項目結(jié)構(gòu)如下所示:

圖 10. 實例項目結(jié)構(gòu)圖
圖 10. 實例項目結(jié)構(gòu)圖 
 

運(yùn)行程序,查看數(shù)據(jù)庫表和運(yùn)行結(jié)果

數(shù)據(jù)庫中,QRTZ_TRIGGERS 表中添加了一條 trigger 記錄,如下所示:

圖 11. QRTZ_TRIGGERS 表中的記錄

圖 11. QRTZ_TRIGGERS 表中的記錄 
 

QRTZ_JOB_DETAILS 表中添加了一條 job 記錄,如下所示:

圖 12. QRTZ_JOB_DETAILES 表中的記錄

圖 12. QRTZ_JOB_DETAILES 表中的記錄 

從運(yùn)行結(jié)果來看,任務(wù)每兩分鐘被執(zhí)行一次:

圖 13. 運(yùn)行結(jié)果

圖 13. 運(yùn)行結(jié)果

#p#

企業(yè)級開發(fā)中的常見應(yīng)用

在應(yīng)用 Quartz 進(jìn)行企業(yè)級的開發(fā)時,有一些問題會經(jīng)常遇到。本節(jié)筆者根據(jù)自己在項目開發(fā)中的經(jīng)驗,介紹企業(yè)開發(fā)中常見的一些問題以及通常的解決辦法。

應(yīng)用一:如何使用不同類型的 Trigger

前面我們提到 Quartz 中四種類型的 Trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger, 和 NthIncludedDayTrigger。

SimpleTrigger 一般用于實現(xiàn)每隔一定時間執(zhí)行任務(wù),以及重復(fù)多少次,如每 2 小時執(zhí)行一次,重復(fù)執(zhí)行 5 次。SimpleTrigger 內(nèi)部實現(xiàn)機(jī)制是通過計算間隔時間來計算下次的執(zhí)行時間,這就導(dǎo)致其不適合調(diào)度定時的任務(wù)。例如我們想每天的 1:00AM 執(zhí)行任務(wù),如果使用 SimpleTrigger 的話間隔時間就是一天。注意這里就會有一個問題,即當(dāng)有 misfired 的任務(wù)并且恢復(fù)執(zhí)行時,該執(zhí)行時間是隨機(jī)的(取決于何時執(zhí)行 misfired 的任務(wù),例如某天的 3:00PM)。這會導(dǎo)致之后每天的執(zhí)行時間都會變成 3:00PM,而不是我們原來期望的 1:00AM。

CronTirgger 類似于 LINUX 上的任務(wù)調(diào)度命令 crontab,即利用一個包含 7 個字段的表達(dá)式來表示時間調(diào)度方式。例如,"0 15 10 * * ? *" 表示每天的 10:1***M 執(zhí)行任務(wù)。對于涉及到星期和月份的調(diào)度,CronTirgger 是最適合的,甚至某些情況下是唯一選擇。例如,"0 10 14 ? 3 WED" 表示三月份的每個星期三的下午 14:10PM 執(zhí)行任務(wù)。讀者可以在具體用到該 trigger 時再詳細(xì)了解每個字段的含義。

DateIntervalTrigger 是 Quartz 1.7 之后的版本加入的,其最適合調(diào)度類似每 N(1, 2, 3...)小時,每 N 天,每 N 周等的任務(wù)。雖然 SimpleTrigger 也能實現(xiàn)類似的任務(wù),但是 DateIntervalTrigger 不會受到我們上面說到的 misfired 任務(wù)的影響。另外,DateIntervalTrigger 也不會受到 DST(Daylight Saving Time, 即中國的夏令時)調(diào)整的影響。筆者就曾經(jīng)因為該原因?qū)㈨椖恐械?SimpleTrigger 改為了 DateIntervalTrigger,因為如果使用 SimpleTrigger,本來設(shè)定的調(diào)度時間就會由于 DST 的調(diào)整而提前或延遲一個小時,而 DateIntervalTrigger 不會受此影響。

NthIncludedDayTrigger 的用途比較簡單明確,即用于每隔一個周期的第幾天調(diào)度任務(wù),例如,每個月的第 3 天執(zhí)行指定的任務(wù)。

除了上面提到的 4 種 Trigger,Quartz 中還定義了一個 Calendar 類(注意,是 org.quartz.Calendar)。這個 Calendar 與 Trigger 一起使用,但是它們的作用相反,它是用于排除任務(wù)不被執(zhí)行的情況。例如,按照 Trigger 的規(guī)則在 10 月 1 號需要執(zhí)行任務(wù),但是 Calendar 指定了 10 月 1 號是節(jié)日(國慶),所以任務(wù)在這一天將不會被執(zhí)行。通常來說,Calendar 用于排除節(jié)假日的任務(wù)調(diào)度,從而使任務(wù)只在工作日執(zhí)行。

應(yīng)用二:使用有狀態(tài)(StatefulJob)還是無狀態(tài)的任務(wù)(Job)

在 Quartz 中,Job 是一個接口,企業(yè)應(yīng)用需要實現(xiàn)這個接口以定義自己的任務(wù)。基本來說,任務(wù)分為有狀態(tài)和無狀態(tài)兩種。實現(xiàn) Job 接口的任務(wù)缺省為無狀態(tài)的。Quartz 中還有另外一個接口 StatefulJob。實現(xiàn) StatefulJob 接口的任務(wù)為有狀態(tài)的,上一節(jié)的簡單實例中,我們定義的 SampleJob 就是實現(xiàn)了 StatefulJob 接口的有狀態(tài)任務(wù)。下圖列出了 Quartz 中 Job 接口的定義以及一些自帶的實現(xiàn)類:

圖 14. Quartz 中 Job 接口定義

圖 14. Quartz 中 Job 接口定義
 

無狀態(tài)任務(wù)一般指可以并發(fā)的任務(wù),即任務(wù)之間是獨(dú)立的,不會互相干擾。例如我們定義一個 trigger,每 2 分鐘執(zhí)行一次,但是某些情況下一個任務(wù)可能需要 3 分鐘才能執(zhí)行完,這樣,在上一個任務(wù)還處在執(zhí)行狀態(tài)時,下一次觸發(fā)時間已經(jīng)到了。對于無狀態(tài)任務(wù),只要觸發(fā)時間到了就會被執(zhí)行,因為幾個相同任務(wù)可以并發(fā) 執(zhí)行。但是對有狀態(tài)任務(wù)來說,是不能并發(fā)執(zhí)行的,同一時間只能有一個任務(wù)在執(zhí)行。

在筆者項目中,某些任務(wù)需要對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行增刪改處理。這些任務(wù)不能并發(fā)執(zhí)行,否則會造成數(shù)據(jù)混亂。因此我們使用 StatefulJob 接口?,F(xiàn)在回到上面的例子,任務(wù)每 2 分鐘執(zhí)行一次,若某次任務(wù)執(zhí)行了 5 分鐘才完成,Quartz 會怎么處理呢?按照 trigger 的規(guī)則,第 2 分鐘和第 4 分鐘分別會有一次預(yù)定的觸發(fā)執(zhí)行,但是由于是有狀態(tài)任務(wù),因此實際不會被觸發(fā)。在第 5 分鐘***次任務(wù)執(zhí)行完畢時,Quartz 會把第 2 和第 4 分鐘的兩次觸發(fā)作為 misfired job 進(jìn)行處理。對于 misfired job,Quartz 會查看其 misfire 策略是如何設(shè)定的,如果是立刻執(zhí)行,則會馬上啟動一次執(zhí)行,如果是等待下次執(zhí)行,則會忽略錯過的任務(wù),而等待下次(即第 6 分鐘)觸發(fā)執(zhí)行。

讀者可以在自己的項目中體會兩種任務(wù)的區(qū)別以及 Quartz 的處理方法,根據(jù)具體情況選擇不同類型的任務(wù)。

應(yīng)用三:如何設(shè)置 Quartz 的線程池和并發(fā)任務(wù)

Quartz 中自帶了一個線程池的實現(xiàn):SimpleThreadPool。類如其名,這只是線程池的一個簡單實現(xiàn),沒有提供動態(tài)自發(fā)調(diào)整等高級特性。Quartz 提供了一個配置參數(shù):org.quartz.threadPool.threadCount,可以在初始化時設(shè)定線程池的線程數(shù)量,但是一次設(shè)定后不能再 修改。假定這個數(shù)目是 10,則在并發(fā)任務(wù)達(dá)到 10 個以后,再有觸發(fā)的任務(wù)就無法被執(zhí)行了,只能等待有空閑線程的時候才能得到執(zhí)行。因此有些 trigger 就可能被 misfire。但是必須指出一點(diǎn),這個初始線程數(shù)并不是越大越好。當(dāng)并發(fā)線程太多時,系統(tǒng)整體性能反而會下降,因為系統(tǒng)把很多時間花在了線程調(diào)度上。根 據(jù)一般經(jīng)驗,這個值在 10 -- 50 比較合適。

對于一些注重性能的線程池來說,會根據(jù)實際線程使用情況進(jìn)行動態(tài)調(diào)整,例如初始線程數(shù),***線程數(shù),空閑線程數(shù)等。讀者在應(yīng)用中,如果有更好 的線程池,則可以在配置文件中通過下面參數(shù)替換 SimpleThreadPool:org.quartz.threadPool.class = myapp.GreatThreadPool。

應(yīng)用四:如何處理 Misfired 任務(wù)

在 Quartz 應(yīng)用中,misfired job 是經(jīng)常遇到的情況。一般來說,下面這些原因可能造成 misfired job:

1)系統(tǒng)因為某些原因被重啟。在系統(tǒng)關(guān)閉到重新啟動之間的一段時間里,可能有些任務(wù)會

被 misfire;

2)Trigger 被暫停(suspend)的一段時間里,有些任務(wù)可能會被 misfire;

3)線程池中所有線程都被占用,導(dǎo)致任務(wù)無法被觸發(fā)執(zhí)行,造成 misfire;

4)有狀態(tài)任務(wù)在下次觸發(fā)時間到達(dá)時,上次執(zhí)行還沒有結(jié)束;

為了處理 misfired job,Quartz 中為 trigger 定義了處理策略,主要有下面兩種:

MISFIRE_INSTRUCTION_FIRE_ONCE_NOW:針對 misfired job 馬上執(zhí)行一次;

MISFIRE_INSTRUCTION_DO_NOTHING:忽略 misfired job,等待下次觸發(fā);

建議讀者在應(yīng)用開發(fā)中,將該設(shè)置作為可配置選項,使得用戶可以在使用過程中,針對已經(jīng)添加的 tirgger 動態(tài)配置該選項。

應(yīng)用五:如何保留已經(jīng)結(jié)束的 Trigger

在 Quartz 中,一個 tirgger 在***一次觸發(fā)完成之后,會被自動刪除。Quartz 默認(rèn)不會保留已經(jīng)結(jié)束的 trigger,如下面 Quartz 源代碼所示:

圖 15. executionComplete( ) 源碼

圖 15. executionComplete( ) 源碼
 

但是在實際應(yīng)用中,有些用戶需要保留以前的 trigger,作為歷史記錄,或者作為以后創(chuàng)建其他 trigger 的依據(jù)。如何保留結(jié)束的 trigger 呢?

一個辦法是應(yīng)用開發(fā)者自己維護(hù)一份數(shù)據(jù)備份記錄,并且與 Quartz 原表的記錄保持一定的同步。這個辦法實際操作起來比較繁瑣,而且容易出錯,不推薦使用。

另外一個辦法是通過修改并重新編譯 Quartz 的 trigger 類,修改其默認(rèn)的行為。我們以 org.quartz.SimpleTrigger 為例,修改上面代碼中 if (!mayFireAgain()) 部分的代碼如下:

圖 16. 修改 executionComplete( ) 源碼

圖 16. 修改 executionComplete( ) 源碼 

另外我們需要在 SimpleTrigger 中定義一個新的類屬性:needRetain,如下所示:

圖 17. 定義新屬性 needRetain

圖 17. 定義新屬性 needRetain
 

在定義自己的 trigger 時,設(shè)置該屬性,就可以選擇是否在 trigger 結(jié)束時刪除 trigger。如下代碼所示:

圖 18. 使用修改后的 SimpleTrigger

圖 18. 使用修改后的 SimpleTrigger
 

有人可能會考慮通過定義一個新的類,然后繼承 org.quartz.SimpleTrigger 類并覆蓋 executionComplete( ) 方法來實現(xiàn)。但是這種方法是行不通的,因為 Quartz 內(nèi)部在處理時會根據(jù) trigger 的類型重新生成 SimpleTrigger 類的實例,而不是使用我們自己定義的類創(chuàng)建的實例。這一點(diǎn)應(yīng)該是 Quartz 的一個小小的不足之處,因為它把擴(kuò)展 trigger 的能力堵死了。好在 Quartz 是開源的,我們可以根據(jù)需要進(jìn)行修改。

小結(jié)

作為當(dāng)前頗具生命力的開源框架,Quartz 已經(jīng)得到了廣泛的應(yīng)用。Quartz 的強(qiáng)大功能和應(yīng)用靈活性,在企業(yè)應(yīng)用中發(fā)揮了巨大的作用。本文描述了如何應(yīng)用 Quartz 開發(fā)應(yīng)用程序,并對企業(yè)應(yīng)用中常見的問題及解決方案進(jìn)行了討論。

原文鏈接:IBM developerWorks

責(zé)任編輯:林師授 來源: IBM/DW
相關(guān)推薦

2009-06-26 14:04:15

Quartz配置

2010-04-07 08:55:00

OSGiSpring

2009-06-19 15:20:08

Quartz任務(wù)調(diào)度Spring

2009-12-14 20:13:57

IBM

2012-05-15 15:21:29

企業(yè)級

2013-01-25 16:54:42

富士通HTML5企業(yè)級

2024-06-11 08:30:25

Quartz.NET開源任務(wù)調(diào)度庫

2012-06-14 13:26:22

2023-06-29 07:55:52

Quartz.Net開源

2010-08-04 15:20:15

Flex企業(yè)級開發(fā)

2011-03-30 14:29:13

QuartzJava

2013-09-30 10:19:46

SAP

2024-11-14 08:10:00

Python開發(fā)

2010-01-04 16:38:07

企業(yè)級Silverli

2021-10-11 14:28:25

TypeScript企業(yè)級應(yīng)用

2009-11-23 20:16:25

ibmdwRational

2011-12-06 14:02:27

企業(yè)級移動開發(fā)

2019-03-05 12:56:41

APP企業(yè)級應(yīng)用應(yīng)用程序

2009-07-07 14:19:54

2013-04-26 15:13:26

Ted YuHBase大數(shù)據(jù)全球技術(shù)峰會
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號