close

點擊關注公眾號,實用技術文章及時了解


一.定時任務概述1.定時任務認識1.1.什麼是定時任務

定時任務是按照指定時間周期運行任務。使用場景為在某個固定時間點執行,或者周期性的去執行某個任務,比如:每天晚上24點做數據匯總,定時發送短信等。

1.2.常見定時任務方案
While + Sleep : 通過循環加休眠的方式定時執行
Timer和TimerTask實現 :JDK自帶的定時任務,可以實現簡單的間隔執行任務(在指定時間點執行某一任務,也能定時的周期性執行),無法實現按日曆去調度執行任務。
ScheduledExecutorService : Java並發包下,JDK1.5出現,是比較理想的定時任務實現方案。Eureka就使用的是它
QuartZ : 使用Quartz,它是一個異步任務調度框架,功能豐富,可以實現按日曆調度,支持持久化。
使用Spring Task,Spring 3.0後提供Spring Task實現任務調度,支持按日曆調度,相比Quartz功能稍簡單,但是在開發基本夠用,支持註解編程方式。
SpringBoot中的Schedule : 通過@EnableScheduling+@Scheduled最實現定時任務,底層使用的是Spring Task
2.分布式定時任務2.1.遇到什麼問題

上述的定時任務都是集中式(單體項目使用)的定時任務,在分布式中將會面臨一些問題或不足

業務量大,單機性能瓶頸需要擴展
多台機器部署如何保證定時任務不重複執行
定時任務時間需要可調整,可以暫停
機器發生故障down機,定時任務依然可用,如何實現故障轉移
定時任務,執行日誌是否可監控
2.2.分布式定時任務xxl-job

XXL-JOB是一個分布式任務調度平台,於2015問世,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。其具備且不止如下能力

簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鐘上手;
動態:支持動態修改任務狀態、啟動/停止任務,以及終止運行中任務,即時生效;
調度中心HA(中心式):調度採用中心式設計,「調度中心」基於集群Quartz實現並支持集群部署,可保證調度中心HA;執行器HA(分布式):任務分布式執行,任務"執行器"支持集群部署,可保證任務執行HA;
彈性擴容縮容:一旦有新執行器機器上線或者下線,下次調度時將會重新分配任務;
路由策略:執行器集群部署時提供豐富的路由策略,包括:第一個、最後一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移、忙碌轉移等;
故障轉移:任務路由策略選擇"故障轉移"情況下,如果執行器集群中某一台機器故障,將會自動Failover切換到一台正常的執行器發送調度請求。
任務失敗告警:默認提供郵件方式失敗告警,同時預留擴展接口,可方面的擴展短信、釘釘等告警方式;

具體見:https://github.com/xuxueli/xxl-job/tree/v2.0.0

二.XXL-JOB初體驗1.xxl-job架構設計1.1.設計思想

將調度行為抽象形成「調度中心」公共平台,而平台自身並不承擔業務邏輯,「調度中心」負責發起調度請求。

將任務抽象成分散的JobHandler,交由「執行器」統一管理,「執行器」負責接收調度請求並執行對應的JobHandler中業務邏輯。因此,「調度」和「任務」兩部分可以相互解耦,提高系統整體穩定性和擴展性;

1.2.架構設計圖

xxl-job分為 調度中心和執行器兩大模塊

調度模塊(調度中心)

負責管理調度信息,按照調度配置發出調度請求,自身不承擔業務代碼。調度系統與任務解耦,提高了系統可用性和穩定性,同時調度系統性能不再受限於任務模塊;

支持可視化、簡單且動態的管理調度信息,包括任務新建,更新,刪除,GLUE開發和任務報警等,所有上述操作都會實時生效,同時支持監控調度結果以及執行日誌,支持執行器Failover(故障轉移)。

執行模塊(執行器)

負責接收調度請求並執行任務邏輯。任務模塊專注於任務的執行等操作,開發和維護更加簡單和高效;

接收「調度中心」的執行請求、終止請求和日誌請求等。

調度中心高可用

基於數據庫的集群方案,數據庫選用Mysql;集群分布式並發環境中進行定時任務調度時,會在各個節點會上報任務,存到數據庫中,執行時會從數據庫中取出觸發器來執行,如果觸發器的名稱和執行時間相同,則只有一個節點去執行此任務。

並行調度

調度採用線程池方式實現,避免單線程因阻塞而引起任務調度延遲。XXL-JOB調度模塊默認採用並行機制,在多線程調度的情況下,調度模塊被阻塞的幾率很低,大大提高了調度系統的承載量。

XXL-JOB的不同任務之間並行調度、並行執行。XXL-JOB的單個任務,針對多個執行器是並行運行的,針對單個執行器是串行執行的。同時支持任務終止。

執行器(任務)高可用

執行器如若集群部署,調度中心將會感知到在線的所有執行器,如「127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999」。多個執行器可以選擇「路由策略」來採用輪詢,隨機等方式進行多機器調度。

當任務」路由策略」選擇」故障轉移(FAILOVER)」時,當調度中心每次發起調度請求時,會按照順序對執行器發出心跳檢測請求,第一個檢測為存活狀態的執行器將會被選定並發送調度請求。調度成功後,可在日誌監控界面查看「調度備註」

2.xxl-job安裝2.1.下載源碼

請下載項目源碼並解壓,使用IDEA工具導入項目

源碼倉庫地址

https://github.com/xuxueli/xxl-job
http://gitee.com/xuxueli0323/xxl-job

項目代碼結構如下

doc :文檔,即SQL腳本所在目錄
db : 「調度數據庫」建表腳本
xxl-job-admin : 調度中心項目源碼
xxl-job-core : 核心模塊,公共Jar依賴
xxl-job-executor-samples : 執行器,Sample示例項目(大家可以在該項目上進行開發,也可以將現有項目改造生成執行器項目)
2.2.導入數據庫

打開項目代碼,獲取 「調度數據庫初始化SQL腳本」 並執行即可。「調度數據庫初始化SQL腳本」 位置為: /xxl-job/doc/db/tables_xxl_job.sql ,數據庫名:xxl_job

數據庫如下

xxl_job_lock:任務調度鎖表;
xxl_job_group:執行器信息表,維護任務執行器信息;
xxl_job_info:調度擴展信息表:用於保存XXL-JOB調度任務的擴展信息,如任務分組、任務名、機器地址、執行器、執行入參和報警郵件等等;
xxl_job_log:調度日誌表:用於保存XXL-JOB任務調度的歷史信息,如調度結果、執行結果、調度入參、調度機器和執行器等等;
xxl_job_log_report:調度日誌報表:用戶存儲XXL-JOB任務調度日誌的報表,調度中心報表功能頁面會用到;
xxl_job_logglue:任務GLUE日誌:用於保存GLUE更新歷史,用於支持GLUE的版本回溯功能;
xxl_job_registry:執行器註冊表,維護在線的執行器和調度中心機器地址信息;
xxl_job_user:系統用戶表;
2.3.啟動調度中心

打開 xxl-job-admin 的配置文件,/xxl-job/xxl-job-admin/src/main/resources/application.properties 對調度中心進行配置,重要配置如下

server.port : 根據情況修改端口
spring.datasource.url :指向剛才準備的數據庫
spring.datasource.password : 記得修改成自己的數據庫密碼
spring.mail.username :配置自己的郵件賬號
spring.mail.password :郵件的授權碼,我下面是以qq郵箱為例

下面根據自己的情況進行修改,不要直接複製

###調度中心JDBC鏈接:鏈接地址請保持和 2.1章節所創建的調度數據庫的地址一致spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaispring.datasource.username=rootspring.datasource.password=root_pwdspring.datasource.driver-class-name=com.mysql.jdbc.Driver###報警郵箱spring.mail.host=smtp.qq.comspring.mail.port=25spring.mail.username=xxx@qq.comspring.mail.password=郵箱授權碼,不是登錄密碼spring.mail.properties.mail.smtp.auth=truespring.mail.properties.mail.smtp.starttls.enable=truespring.mail.properties.mail.smtp.starttls.required=truespring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory###調度中心通訊TOKEN [選填]:非空時啟用;xxl.job.accessToken=###調度中心國際化配置[必填]:默認為"zh_CN"/中文簡體, 可選範圍為"zh_CN"/中文簡體, "zh_TC"/中文繁體 and "en"/英文;xxl.job.i18n=zh_CN##調度線程池最大線程配置【必填】xxl.job.triggerpool.fast.max=200xxl.job.triggerpool.slow.max=100###調度中心日誌表數據保存天數[必填]:過期日誌自動清理;限制大於等於7時生效,否則, 如-1,關閉自動清理功能;xxl.job.logretentiondays=30

然後啟動調度中心 ,執行 XxlJobAdminApplication#main 方法 , 啟動之後,瀏覽器訪問 http://localhost:18080/xxl-job-admin/jobinfo?jobGroup=2 ;注意URL中有個上下文路徑。默認登錄賬號 「admin/123456」, 登錄後運行界面如下圖所示。

2.3.配置部署「執行器項目

「執行器」項目:xxl-job-executor-sample-springboot (提供多種版本執行器供選擇,現以 springboot 版本為例,可直接使用,也可以參考其並將現有項目改造成執行器)

作用:負責接收「調度中心」的調度並執行;可直接部署執行器,也可以將執行器集成到現有業務項目中。

修改配置:/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties

xxl.job.admin.addresses : 調度中心的地址,如果調度中心修改過端口,這裡也要對應修改
###調度中心部署跟地址[選填]:如調度中心集群部署存在多個地址則用逗號分隔。執行器將會使用該地址進行"執行器心跳註冊"和"任務結果回調";為空則關閉自動註冊;xxl.job.admin.addresses=http://127.0.0.1:18080/xxl-job-admin###執行器通訊TOKEN [選填]:非空時啟用;xxl.job.accessToken=###執行器AppName [選填]:執行器心跳註冊分組依據;為空則關閉自動註冊xxl.job.executor.appname=xxl-job-executor-sample###執行器註冊[選填]:優先使用該配置作為註冊地址,為空時使用內嵌服務」IP:PORT「作為註冊地址。從而更靈活的支持容器類型執行器動態IP和動態映射端口問題。xxl.job.executor.address=###執行器IP [選填]:默認為空表示自動獲取IP,多網卡時可手動設置指定IP,該IP不會綁定Host僅作為通訊實用;地址信息用於"執行器註冊"和"調度中心請求並觸發任務";xxl.job.executor.ip=###執行器端口號[選填]:小於等於0則自動獲取;默認端口為9999,單機部署多個執行器時,注意要配置不同執行器端口;xxl.job.executor.port=9999###執行器運行日誌文件存儲磁盤路徑[選填]:需要對該路徑擁有讀寫權限;為空則使用默認路徑;xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler###執行器日誌文件保存天數[選填]:過期日誌自動清理, 限制值大於等於3時生效;否則, 如-1, 關閉自動清理功能;xxl.job.executor.logretentiondays=30

上面配置是為了在Spring容器中創建一個 XxlJobSpringExecutor 執行器Bean,見:com.xxl.job.executor.core.config.XxlJobConfig#xxlJobExecutor

@BeanpublicXxlJobSpringExecutorxxlJobExecutor(){logger.info(">>>>>>>>>>>xxl-jobconfiginit.");XxlJobSpringExecutorxxlJobSpringExecutor=newXxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);returnxxlJobSpringExecutor;}

在com.xxl.job.executor.service.jobhandler.SampleXxlJob中提供了簡單的定時任務實例

為方便用戶參考與快速實用,示例執行器內原生提供多個Bean模式任務Handler,可以直接配置實用,如下:

demoJobHandler:簡單示例任務,任務內部模擬耗時任務邏輯,用戶可在線體驗Rolling Log等功能;
shardingJobHandler:分片示例任務,任務內部模擬處理分片參數,可參考熟悉分片任務;
httpJobHandler:通用HTTP任務Handler;業務方只需要提供HTTP鏈接等信息即可,不限制語言、平台。示例任務入參如下:
/***XxlJob開發示例(Bean模式)**開發步驟:*1、在SpringBean實例中,開發Job方法,方式格式要求為"publicReturnT<String>execute(Stringparam)"*2、為Job方法添加註解"@XxlJob(value="自定義jobhandler名稱", init ="JobHandler初始化方法", destroy ="JobHandler銷毀方法")",註解value值對應的是調度中心新建任務的JobHandler屬性的值。* 3、執行日誌:需要通過"XxlJobLogger.log"打印執行日誌;**@authorxuxueli2019-12-1121:52:51*/@ComponentpublicclassSampleXxlJob{privatestaticLoggerlogger=LoggerFactory.getLogger(SampleXxlJob.class);/***1、簡單任務示例(Bean模式)*/@XxlJob("demoJobHandler")publicReturnT<String>demoJobHandler(Stringparam)throwsException{logger.info("XXL-JOB,HelloWorld.param={}",param);returnReturnT.SUCCESS;}//...省略...}

【重要】 如果我們要寫自己的定時任務,參照上面方法,在方法上註解一個@XxlJob("任務名字") ,方法可以接受一個字符串參數,方法需要返回ReturnT格式。

最後啟動執行器項目.

3.配置定時任務3.1.執行器創建

打開調度中心可視化界面,在執行器管理界面,添加新增執行器

appName : 執行器的名字,可以任意填寫

名稱:任意填寫

註冊方式:調度中心是通過RPC的方式對執行器發起調度,所以這裡需要的是執行器項目的ip:port ,注意,該端口不是執行器項目的server.port ,而是:xxl.job.executor.port 端口。你可以選擇自動註冊,也可以手動錄入。

3.2.創建任務

在 任務管理 界面,新增任務

路由策略:有輪詢,隨機,故障轉移等等策略,是用在集群模式下的調度方式。
cron : 定時任務的執行時間規則,時間表達式
JobHandler : 這個是要對應 「執行器項目」中 @XxlJob("demoJobHandler") 註解中的名字
運行模式 :Bean ,使用內置代碼方式,也可以執行在線執行代碼方式
報警郵件 :如果定時任務失敗,會發送報警郵件到郵箱
任務參數:這個參數可以傳遞給 @XxlJob("demoJobHandler")所在方法的參數。

創建好任務之後就可以執行了

調度日誌

IDEA工具控制台效果

15:47:33.017logback[Thread-16]INFOc.x.j.e.s.jobhandler.SampleXxlJob-XXL-JOB,HelloWorld.param=15:47:34.007logback[Thread-16]INFOc.x.j.e.s.jobhandler.SampleXxlJob-XXL-JOB,HelloWorld.param=15:47:35.008logback[Thread-16]INFOc.x.j.e.s.jobhandler.SampleXxlJob-XXL-JOB,HelloWorld.param=...省略...4.GLUE模式(Java)4.1.添加任務

該模式支持在線編輯定時任務的內容,立刻執行,無需再開發工具中編輯代碼,也無需重啟項目。

請點擊任務右側 「GLUE」 按鈕,進入 「GLUE編輯器開發界面」 ,見下圖。「GLUE模式(Java)」 運行模式的任務默認已經初始化了示例任務代碼,即打印Hello World。

任務以源碼方式維護在調度中心,支持通過Web IDE在線更新,實時編譯和生效,因此不需要指定JobHandler

4.2.編寫代碼

保存之後可以在操作按鈕裡面去編寫任務

(「GLUE模式(Java)」 運行模式的任務實際上是一段繼承自IJobHandler的Java類代碼,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器里中的其他服務),比如我的定時任務如下,編輯好之後點擊保存

保存好之後,啟動定時任務,效果如下

三.XXL-JOB集群部署1.調度中心集群1.1.問題概述

調度中心支持集群部署,提升調度系統容災和可用性。調度中心集群部署時,幾點要求和建議:

DB配置保持一致;
集群機器時鐘保持一致(單機集群忽視);
當啟動多個調度器時,執行器配置調度中心部署跟地址可以用逗號分隔。執行器將會使用該地址進行"執行器心跳註冊"和"任務結果回調";為空則關閉自動註冊;

但是建議:推薦通過nginx為調度中心集群做負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操作均通過該域名進行。

1.2.啟動多個調度中心

修改調度中心端口,啟動多個調度中心,我這裡啟動兩個如

http://localhost:18080/xxl-job-admin/
http://localhost:18081/xxl-job-admin/
1.3.配置Nginx負載均衡

當啟動多個調度器時,執行器配置調度中心部署跟地址可以用逗號分隔。執行器將會使用該地址進行「執行器心跳註冊」和「任務結果回調」;為空則關閉自動註冊;

但是建議:推薦通過nginx為調度中心集群做負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操作均通過該域名進行。

我們啟動了2個調度中心,那麼我的執行器項目該註冊到哪個調度中心呢?我們通過Nginx來解決這個問題,原理如下圖:

我們再hosts配置 www.jobs.com作為nginx的主機域名,然後反向代理到多個調度中心,這樣一來執行器就只需要註冊到www.jobs.com Nginx即可。

修改 C:\Windows\System32\drivers\etc\hosts增加配置如下

127.0.0.1www.jobs.com

Nginx配置如下

#調度中心upstreamjobs{serverlocalhost:18080;serverlocalhost:18081;}server{listen80;#使用域名server_namewww.jobs.com;#charsetkoi8-r;#access_loglogs/host.access.logmain;location/{#調度中心反向代理配置proxy_passhttp://jobs/;}#error_page404/404.html;#redirectservererrorpagestothestaticpage/50x.html#error_page500502503504/50x.html;location=/50x.html{roothtml;}}

啟動Nginx,通過瀏覽器訪問 http://www.jobs.com/xxl-job-admin/ ,可以訪問到調度中心的管理界面

2.執行器項目集群

執行器支持集群部署,提升調度系統可用性,同時提升任務處理能力。

執行器集群部署時,幾點要求和建議:

執行器回調地址(xxl.job.admin.addresses)需要保持一致;執行器根據該配置進行執行器自動註冊等操作。
同一個執行器集群內AppName(xxl.job.executor.appname)需要保持一致;調度中心根據該配置動態發現不同集群的在線執行器列表。
2.1.啟動多個執行器項目

現在對執行器項目做集群,修改xxl-job-executor-sample-springboot配置文件application.properties

server.port : 既然是做集群,項目端口需要修改
xxl.job.admin.addresses : 調度中心地址需要修改成www.jobs.com ,多個執行器配置同一個地址。
xxl.job.executor.port : RPC通信端口也要修改,多個執行器該端口需要不一樣

第一個實例配置

server.port=19090xxl.job.admin.addresses=http://www.jobs.com/xxl-job-admin#對應Nginx地址xxl.job.executor.port=9999

第二個實例配置

server.port=19091xxl.job.admin.addresses=http://www.jobs.com/xxl-job-adminxxl.job.executor.port=9998

在 Configurations中配置,允許啟動多個實例

啟動實例如下

2.2.配置定時任務

通過http://www.jobs.com/xxl-job-admin 訪問調度中心管理界面,在執行器管理中可以看到多台執行器實例

在任務管理中,可以編輯任務,然後選擇路由策略,比如:選擇輪詢,然後啟動任務,就會看到兩個執行器項目輪着執行定時任務。

說在最後

xxl-job確實很強大,功能也很全,經過該文章學習相信你可以把xxl-job給用起來了,但是如果你的項目是一個小體量的單體,我不太建議使用它,Quzrtz或者SpringBoot Task就足夠 ,對於xxl-job個人還是有些笨重。

來源:blog.csdn.net/u014494148/article/
details/121382211

推薦

Java面試題寶典

技術內卷群,一起來學習!!

PS:因為公眾號平台更改了推送規則,如果不想錯過內容,記得讀完點一下「在看」,加個「星標」,這樣每次新文章推送才會第一時間出現在你的訂閱列表里。點「在看」支持我們吧!

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()