国产乱人伦精品一区二区,国产在线麻豆精品观看,国产在线播精品第三,亚洲欧美国产制服动漫

您的位置:首頁>24小時 >

【定時調度】- 01 quartz的基礎你真的了解嗎

來源:騰訊云  

概述

Quartz一款功能豐富、歷史悠久,完全基于Java實現的開源任務調度框架,Java調度領域知名度非常高。其簡單易用、穩定可靠的特性,使其被很多第三方應用將其當成調度框架基礎依賴,如spring boot已內置集成quartzelastic-job調度框架則將quartz作為其底層基礎實現進行封裝,xxl-job曾經歷史版本也是集成quartz作為其觸發實現機制基礎,不過在最新版本采用時間輪實現已將quartz移除。


(資料圖片僅供參考)

核心三叉戟

使用quartz api時,最核心三件套如下:

Scheduler

SchedulerFactoryScheduler從名稱就很容易識別這里采用工廠設計模式,Schedulerquartz暴露出來供開發使用的一個最重要組件,從開發者視角來看它就是quartz的門面,對quartz的各種操作都是通過Scheduler進行串聯,類似于quartz的大管家、代言人角色。

“這種設計模式在開源框架中很常見,比如mybatisSqlSessionFactorySqlSession,通過給開發者提供大管家組件,通過一個組件串聯起所有核心功能,簡化了開發人員上手框架難度。

一般一個應用只會對應一個Scheduler實例,不同Scheduler實例之間通過schedulerName進行隔離,所有的quartz數據庫表設計中都有sched_name這一列字段,這樣Scheduler處理任務時只會操作數據庫表中對應schedulerName下的數據。quartz集群就是利用多個Scheduler實例配置相同schedulerName名稱,實現多機器同時處理同一個schedulerName下任務來達到集群效果。

schedulerName可以通過org.quartz.scheduler.instanceName進行配置,默認名稱為QuartzScheduler。

Scheduler操作的主要是JobDetailTrigger兩個組件,JobDetail封裝的是任務配置信息,而Trigger觸發器封裝了任務觸發信息,它們是1:N關系,即一個JobDetail可以關聯多個Trigger觸發器,但是一個Trigger觸發器只能綁定到一個Job上。

JobDetail

JobDetail組件封裝了quartz調度任務定義信息,下面是JobDetail組件常規使用方式如下:

// JobDataMap實現Map接口,任務調度時存儲到JobExecuteContext中,可以傳遞給Job實例JobDataMap jobDataMap = new JobDataMap();jobDataMap.put("name", "zhangsan");jobDataMap.put("time", System.currentTimeMillis());JobDetail jobDetail = JobBuilder      // 綁定任務類            .newJob(QuartzCronJob.class)            .storeDurably()      // job對應ID            .withIdentity("job2", "DEFAULT")             .usingJobData(jobDataMap)            .build();JobKey jobKey = jobDetail.getKey();if (scheduler.checkExists(jobKey)) { log.warn("調度任務已存在,刪除后重新添加:{}", jobKey); scheduler.interrupt(jobKey);//停止JOB    /**      * deleteJob操作在刪除Job之前,會執行unscheduleJob()取消job和trigger關聯    */    scheduler.deleteJob(jobKey);}// 將JobDetail任務定義信息插入quartz表scheduler.addJob(jobDetail, true);

JobDetail操作比較簡單,主要有兩點需要注意:1、newJob(Class jobClass)操作綁定任務類,任務類就是封裝用戶業務邏輯類;2、withIdentity(String name, String group)給該任務設置一個身份ID,后續可以通過該身份ID進行管理,為方便靈活管理quartz抽象出group概念,這樣可以批量對一組作業進行批量操作,身份ID使用JobKey進行封裝。

使用ScheduleraddJob(JobDetail jobDetail, boolean replace)方法就將創建的Job定義信息添加到quartz中,一般采用數據庫持久化模式,即這里就會將Job定義信息插入到qrtz_job_details表中(見下圖)。

下面來看下幾個關鍵字段:

sched_name:上面說過,用來關聯對應的Scheduler實例is_durable:是否持久化is_nonconcurrent:是否允許同一個作業可以同時多個實例執行,比如一個任務間隔1秒,但其執行時間為2秒,通過該屬性控制是否允許同一個作業有多個任務同時允許,參見@DisallowConcurrentExecutionis_update_data: 任務已經執行中,是否允許更新JobDataMap持久化信息,參見@PersistJobDataAfterExecutionrequests_recovery: 故障恢復使用,具體參見后續源碼分析job_data:JobDataMap序列化后存儲到字段中

Trigger

任務定義完成,但是任務按照怎么周期性規則進行觸發執行,這就要看Trigger觸發器的臉色了

Trigger組件常規使用方式如下:

JobDataMap jobDataMap = new JobDataMap();jobDataMap.put("name", "lisi");jobDataMap.put("address", "China");Trigger trigger = TriggerBuilder            .newTrigger()            .withIdentity("trigger1", "DEFAULT")            .usingJobData(jobDataMap)            .startAt(new Date())            .endAt(new Date(System.currentTimeMillis()+38 * 60 * 1000))            .withSchedule(CronScheduleBuilder.cronSchedule("*/10 * * * * ?"))            .forJob(new JobKey("job1", "DEFAULT"))            .build();//時間TriggerKey triggerKey = trigger.getKey();if(scheduler.checkExists(triggerKey)){ scheduler.unscheduleJob(triggerKey);}//必須綁定jobscheduler.scheduleJob(trigger);

JobDetail類似,主要有兩點需要注意:1、同withIdentity(String name, String group),同理給該觸發器設置一個身份ID,對應TriggerKey;2、startAt()、endAt()對應啟止時間;3、withSchedule(CronScheduleBuilder.cronSchedule("*/10 * * * * ?"));4、forJob(JobKey keyOfJobToFire)TriggerJob進行關聯,這樣才知道觸發哪個任務。

最后通過SchedulerscheduleJob(Trigger trigger)方法就將創建的Trigger定義信息添加到quartz中,一般采用數據庫持久化模式,即這里就會將Trigger定義信息插入到觸發器相關表中,示例中使用cron觸發器,則插入到qrtz_cron_triggers表中(見下圖)。

下面我們就來看下任務是咋個觸發的。SchedulerscheduleJob(Trigger trigger)將觸發器持久化后,你會發現qrtz_cron_triggers中沒有起止時間以及和Job綁定內容,所以,接下來我們看一張非常重要表:qrtz_triggers。scheduleJob()方法在持久化Trigger信息后會同時向qrtz_triggers表插入一條記錄(見下圖):

qrtz_job_detailsqrtz_cron_triggers可以看成靜態表,那qrtz_triggers就是運行動態表,保存著任務運行期間數據,且隨著運行記錄在動態變更,是quartz調度任務運行最重要的一張表,下面我們來看下這張表中幾個關鍵字段:

start_time、end_time: trigger定義時設置的起止時間next_fire_time: 下次觸發時間戳prev_fire_time: 上次觸發時間戳trigger_state: trigger狀態,最常見狀態WAITING、ACQUIRED和EXECUTING,分別對應等待(下次觸發時間還早) -> 加載到內存中等待(下次觸發時間快到了) --> 執行(下次觸發時間到了,需要觸發任務),具體參見后續源碼分析misfire_instr: trigger觸發時間過期處理策略,比如本來是10:23:50時間點進行觸發,但是由于某些原因在10:23:53秒才檢索出來,這是該觸發時間點已經過期,misfire_instr就是控制采用什么策略處理該過期任務,是直接丟棄重新計算下次觸發時間點、還是一定時間范圍內過期的理解執行等等,具體參見后續源碼分析job_data: 和JobDetail一樣,Trigger也可綁定一個JobDataMap,用于向Job實例傳遞參數,該字段就是存儲Trigger關聯的JobDataMap序列化內容

quartz基本上就是圍繞qrtz_triggers中這幾個關鍵字段實現任務觸發,我們連蒙帶猜大致可以想出quartz任務調度觸發機制粗略流程:

1、通過配置的trigger觸發器,計算出下次觸發時間,更新到next_fire_time字段,同時更新trigger_state狀態為WAITING

2、quartz線程掃描該表,從表中查詢出未來很短一段時間將要觸發的記錄(比對next_fire_time和當前時間)放入到內存排隊隊列中,然后將trigger_state更新成ACQUIRED;

3、然后阻塞直到內存排隊隊列中觸發任務到時間點,再觸發任務之前,重新計算下次觸發時間點,更新到next_fire_time,同時將trigger_state更新為WAITING,然后執行當前任務;

4、由于next_fire_timetrigger_state值更新,重新開始步驟1,就這樣循環往復觸發下去。

總結

這節從一個使用者角度簡單分析quartz核心運行機制,由于只是簡單的從外層而未深入剖析源碼,只是簡單結合數據庫表信息對quartz大致的運行機制做個簡單猜想,一些重要屬性也沒展開,帶著這些疑問下一節通過源碼分析找到真實的答案,一步步加深對quartz運行機制的理解。

關鍵詞:

最新文章
国产乱人伦精品一区二区,国产在线麻豆精品观看,国产在线播精品第三,亚洲欧美国产制服动漫
亚洲精选一区| 国产精品永久入口久久久| 欧美一区在线视频| 亚洲缚视频在线观看| 免费在线成人| 欧美精品色一区二区三区| 国产亚洲一区二区在线观看| 亚洲永久精品国产| 久久精品亚洲热| 久久久999精品| 欧美激情一区二区三区| 欧美日本国产视频| 国产精品嫩草影院av蜜臀| 国产一区二区三区日韩欧美| 国产亚洲精品v| 亚洲视频免费在线观看| 亚洲国产视频直播| 亚洲精品久久| 久久全国免费视频| 国产综合第一页| 久久亚洲精选| 亚洲午夜未删减在线观看| 亚洲第一页在线| 亚洲激情欧美激情| 一卡二卡3卡四卡高清精品视频| 久久美女艺术照精彩视频福利播放| 欧美精品一区二区在线观看| 在线视频精品| 国产精品视频男人的天堂| 久久久久久香蕉网| 欧美在线综合| 一区二区三区免费看| 欧美性片在线观看| 国产美女高潮久久白浆| 亚洲精品国产无天堂网2021| 国产女精品视频网站免费| 亚洲欧洲综合另类| 亚洲综合久久久久| 久久久青草青青国产亚洲免观| 国产精品久久久久久五月尺| 亚洲视频在线观看免费| 免费人成网站在线观看欧美高清| 欧美日本不卡高清| 韩国在线视频一区| 国产精品久久久久久模特| 欧美午夜大胆人体| 久久永久免费| 国产一区二区三区久久精品| 亚洲一区二区av电影| 欧美一区二区大片| 国产欧美日韩另类视频免费观看| 国产主播一区二区| 欧美成人午夜免费视在线看片| 久久久久久999| 久久国产婷婷国产香蕉| 亚洲综合三区| 久久成人精品视频| 午夜久久久久久久久久一区二区| 99精品久久| 在线激情影院一区| 免费观看30秒视频久久| 欧美日韩一级片在线观看| 欧美成人精品一区二区| 国产精品xxxxx| 欧美午夜影院| 99re热这里只有精品免费视频| 亚洲在线免费| 亚洲视屏一区| 蜜桃av噜噜一区| 日韩亚洲综合在线| 国产日韩欧美91| 亚洲日韩第九十九页| 狠狠爱www人成狠狠爱综合网| 一区二区在线看| 亚洲激情av在线| 一区精品久久| 91久久极品少妇xxxxⅹ软件| 免费毛片一区二区三区久久久| 久久久久久久一区| 99精品欧美| 久久av一区二区三区亚洲| 久久在线免费视频| 狂野欧美激情性xxxx欧美| 国产综合视频在线观看| 午夜影视日本亚洲欧洲精品| 欧美一区二区视频在线| 国产欧美短视频| 国产精品美女久久久| 欧美一级电影久久| 欧美激情在线狂野欧美精品| 亚洲精品国产精品乱码不99| 亚洲一区欧美二区| 亚洲高清资源综合久久精品| 免费久久精品视频| 欧美午夜久久久| 欧美日韩国产精品专区| 欧美性淫爽ww久久久久无| 久久久久久穴| 欧美视频中文一区二区三区在线观看| 影音先锋日韩有码| 亚洲精品国精品久久99热| 国产精品一区二区三区四区五区| 欧美韩日亚洲| 欧美成人午夜剧场免费观看| 亚洲国产免费| 亚洲欧洲另类国产综合| 久久精品国产亚洲精品| 久久国产直播| 欧美日韩一区二区三区免费| 欧美精品999| 永久域名在线精品| 欧美日韩一区二区三区在线看| 亚洲成色777777女色窝| 午夜精品一区二区三区在线播放| 亚洲网在线观看| 中文亚洲视频在线| 欧美成人日本| 欧美三区免费完整视频在线观看| 国产精品任我爽爆在线播放| 国产精品久久中文| 亚洲精品一区二区三区婷婷月| 久久成人在线| 国内一区二区三区在线视频| 在线播放亚洲| 国产一区二区三区高清在线观看| 欧美高清在线一区二区| 亚洲主播在线| 国外视频精品毛片| 国产日韩综合一区二区性色av| 国产日韩欧美三区| 99热精品在线观看| 久久aⅴ国产紧身牛仔裤| 国产日韩精品视频一区二区三区| 久久国产精品72免费观看| 欧美在线观看天堂一区二区三区| 国产精品久久久久久久久久直播| 一区二区三区我不卡| 欧美激情麻豆| 久久久亚洲成人| 亚洲制服少妇| 欧美区国产区| 毛片精品免费在线观看| 免费高清在线一区| 久久亚洲欧美| 亚洲高清在线视频| 一区二区在线视频| 午夜视频在线观看一区二区| 国产精品爱啪在线线免费观看| 一本久久综合亚洲鲁鲁五月天| 国产精品每日更新| 老鸭窝91久久精品色噜噜导演| 亚洲三级电影在线观看| 亚洲午夜久久久久久尤物| 亚洲欧美日韩一区| 国产精品视频久久| 亚洲男女毛片无遮挡| 欧美精品一区二区三区在线看午夜| 久久天堂精品| 欧美日韩国产精品一区| 91久久国产自产拍夜夜嗨| 国产精品久久777777毛茸茸| 亚洲精品国产精品乱码不99| 久久久久久色| 欧美精品一区二| 欧美日韩国产精品一区二区亚洲| 欧美日韩精品一区二区三区四区| 最新国产拍偷乱拍精品| 欧美日韩黄色一区二区| 久久精品国产99国产精品| 欧美一级二级三级蜜桃| 国内精品久久久久伊人av| 亚洲在线视频免费观看| 国产婷婷色一区二区三区| 国产精品二区三区四区| 国产日韩欧美三区| 99精品久久久| 黄色在线一区| 国产精品日韩精品欧美在线| 欧美日韩在线播放一区二区| 欧美国产免费| 欧美在线观看一区| 亚洲欧美视频| 亚洲欧美国产一区二区三区| 一区二区三区欧美在线| 毛片精品免费在线观看| 欧美精品 国产精品| 亚洲影音一区| 国产欧美日韩综合一区在线播放| 国产精品婷婷午夜在线观看| 久久一区二区三区超碰国产精品| 国产精品免费网站| 欧美亚洲视频在线看网址| 国产农村妇女精品一区二区| 欧美中文字幕第一页| 国产亚洲精品综合一区91| 欧美系列亚洲系列| 亚洲一区国产一区| 国产精品男女猛烈高潮激情| 亚洲欧洲久久| 亚洲一区国产|