分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作過程(推薦)
一、定時(shí)任務(wù)的使用場(chǎng)景和常見的定時(shí)任務(wù)
某個(gè)時(shí)間定時(shí)處理某個(gè)任務(wù)、發(fā)郵件、短信、消息提醒、訂單通知、統(tǒng)計(jì)報(bào)表等
定時(shí)任務(wù)劃分
單機(jī)定時(shí)任務(wù):
單機(jī)的容易實(shí)現(xiàn),但應(yīng)用于集群環(huán)境做分布式部署,就會(huì)帶來重復(fù)執(zhí)行
解決方案有很多比如加鎖、數(shù)據(jù)庫等,但是增加了很多非業(yè)務(wù)邏輯
分布式調(diào)度:
把需要處理的計(jì)劃任務(wù)放入到統(tǒng)一的平臺(tái),實(shí)現(xiàn)集群管理調(diào)度與分布式部署的定時(shí)任務(wù) 叫做分布式定時(shí)任務(wù)
支持集群部署、高可用、并行調(diào)度、分片處理等
常見定時(shí)任務(wù):
單機(jī):Java自帶的java.util.Timer類配置比較麻煩,時(shí)間延后問題
單機(jī):ScheduledExecutorService
是基于線程池來進(jìn)行設(shè)計(jì)的定時(shí)任務(wù)類,在這里每個(gè)調(diào)度的任務(wù)都會(huì)分配到線程池里的一個(gè)線程去執(zhí)行該任務(wù),并發(fā)執(zhí)行,互不影響單機(jī):SpringBoot框架自帶
SpringBoot使用注解方式開啟定時(shí)任務(wù)
啟動(dòng)類里面 @EnableScheduling開啟定時(shí)任務(wù),自動(dòng)掃描
定時(shí)任務(wù)業(yè)務(wù)類 加注解 @Component被容器掃描
定時(shí)執(zhí)行的方法加上注解 @Scheduled(fixedRate=2000) 定期執(zhí)行一次分布式任務(wù)調(diào)度框架 Elastic-Job/XXL-Job/Quartz
二、如何選擇哪一個(gè)分布式任務(wù)調(diào)度平臺(tái)
Elastic-job和XXL-JOB對(duì)比圖
XXL-Job和Elastic-Job都具有廣泛的用戶基礎(chǔ)和完善的技術(shù)文檔,都可以滿足定時(shí)任務(wù)的基本功能需求
xxl-job側(cè)重在業(yè)務(wù)實(shí)現(xiàn)簡(jiǎn)單和管理方便,容易學(xué)習(xí),失敗與路由策略豐富, 推薦使用在用戶基數(shù)相對(duì)較少,服務(wù)器的數(shù)量在一定的范圍內(nèi)的場(chǎng)景下使用elastic-job關(guān)注的點(diǎn)在數(shù)據(jù),添加了彈性擴(kuò)容和數(shù)據(jù)分片的思路,更方便利用分布式服務(wù)器的資源, 但是學(xué)習(xí)難度較大,推薦在數(shù)據(jù)量龐大,服務(wù)器數(shù)量多的時(shí)候使用
三、xxl-job的設(shè)計(jì)思想
將調(diào)度行為抽象形成“調(diào)度中心”公共平臺(tái),而平臺(tái)自身并不承擔(dān)業(yè)務(wù)邏輯,“調(diào)度中心”負(fù)責(zé)發(fā)起調(diào)度請(qǐng)求。
將任務(wù)抽象成分散的JobHandler,交由“執(zhí)行器”統(tǒng)一管理
“執(zhí)行器”負(fù)責(zé)接收調(diào)度請(qǐng)求并執(zhí)行對(duì)應(yīng)的JobHandler中業(yè)務(wù)邏輯。
因此,“調(diào)度”和“任務(wù)”兩部分可以相互解耦,提高系統(tǒng)整體穩(wěn)定性和擴(kuò)展性
架構(gòu)系統(tǒng)組成:
調(diào)度中心
負(fù)責(zé)管理調(diào)度的信息,按照調(diào)度的配置來發(fā)出調(diào)度請(qǐng)求
支持可視化、簡(jiǎn)單的動(dòng)態(tài)管理調(diào)度信息,包括新建、刪除、更新等,這些操作都會(huì)實(shí)時(shí)生效,同時(shí)也支持監(jiān)控調(diào)度結(jié)果以及執(zhí)行日志。
執(zhí)行器
負(fù)責(zé)接收請(qǐng)求并且執(zhí)行任務(wù)的邏輯。任務(wù)模塊專注于任務(wù)的執(zhí)行操作等等,使得開發(fā)和維護(hù)更加的簡(jiǎn)單與高效
架構(gòu)圖(圖片來源是xxl-job官網(wǎng))
四、XXL-Job具有哪些特性
調(diào)度中心HA(中心式):調(diào)度采用了中心式進(jìn)行設(shè)計(jì),“調(diào)度中心”支持集群部署,可保證調(diào)度中心HA
執(zhí)行器HA(分布式):任務(wù)分布式的執(zhí)行,任務(wù)執(zhí)行器支持集群部署,可保證任務(wù)執(zhí)行HA
觸發(fā)策略:有Cron觸發(fā)、固定間隔觸發(fā)、固定延時(shí)觸發(fā)、API事件觸發(fā)、人工觸發(fā)、父子任務(wù)觸發(fā)
路由策略:執(zhí)行器在集群部署的時(shí)候提供了豐富的路由策略,如:第一個(gè)、最后一個(gè)、輪詢、隨機(jī)、一致性HASH、最不經(jīng)常使用LFU、最久未使用LRU、故障轉(zhuǎn)移等等
故障轉(zhuǎn)移:如果執(zhí)行器集群的一臺(tái)機(jī)器發(fā)生故障,會(huì)自動(dòng)切換到一臺(tái)正常的執(zhí)行器發(fā)送任務(wù)調(diào)度
Rolling實(shí)時(shí)日志的監(jiān)控:支持rolling方式查看輸入的完整執(zhí)行日志
腳本任務(wù):支持GLUE模式開發(fā)和運(yùn)行腳本任務(wù),包括Shell、python、node.js、php等等類型腳本
五、XXL-Job實(shí)戰(zhàn)操作
搭建XXL-Job相關(guān)環(huán)境步驟:
創(chuàng)建數(shù)據(jù)庫腳本
部署XXL-Job服務(wù)端
客戶端項(xiàng)目添加依賴
注意
Client-Server通信,需要網(wǎng)絡(luò)互通才行
所以不能一個(gè)是阿里云ECS,一個(gè)是本地電腦
建議:本地電腦安裝Docker,或者本地Linux虛擬機(jī)安裝Docker部署
本博文是直接拉取的源碼然后在本地win7打包部署的。
步驟一: 進(jìn)入GitHub - xuxueli/xxl-job at 2.2.0地址,根項(xiàng)目需求拉取對(duì)應(yīng)版本代碼
下載壓縮包,這里下載的版本需要跟后面依賴的版本一致,切換到2.2.0版本下載壓縮包。
第二步:
下載后再idea中打開
第三步 打開doc文件夾,找到里面的db tables_xxl_job.sql,然后拿到navicat中運(yùn)行
數(shù)據(jù)庫腳本(使用mysql8)
xxl_job 的數(shù)據(jù)庫里有如下幾個(gè)表
xxl_job_group:執(zhí)行器信息表,用于維護(hù)任務(wù)執(zhí)行器的信息
xxl_job_info:調(diào)度擴(kuò)展信息表,主要是用于保存xxl-job的調(diào)度任務(wù)的擴(kuò)展信息,比如說像任務(wù)分組、任務(wù)名、機(jī)器的地址等等
xxl_job_lock:任務(wù)調(diào)度鎖表
xxl_job_log:日志表,主要是用在保存xxl-job任務(wù)調(diào)度歷史信息,像調(diào)度結(jié)果、執(zhí)行結(jié)果、調(diào)度入?yún)⒌鹊?br />xxl_job_log_report:日志報(bào)表,會(huì)存儲(chǔ)xxl-job任務(wù)調(diào)度的日志報(bào)表,會(huì)在調(diào)度中心里的報(bào)表功能里使用到
xxl_job_logglue:任務(wù)的GLUE日志,用于保存GLUE日志的更新歷史變化,支持GLUE版本的回溯功能
xxl_job_registry:執(zhí)行器的注冊(cè)表,用在維護(hù)在線的執(zhí)行器與調(diào)度中心的地址信息
xxl_job_user:系統(tǒng)的用戶表
更改剛拉下代碼配置中的數(shù)據(jù)庫連接:
本地打包啟動(dòng):
mvn install
jar -jar win7啟動(dòng)xxl-job服務(wù)包
第四步:
訪問地址:http://127.0.0.1:8080/xxl-job-admin/ admin/123456
初次進(jìn)來的運(yùn)行報(bào)表:
以圖形化來展示了整體的任務(wù)執(zhí)行情況
任務(wù)數(shù)量:能夠看到調(diào)度中心運(yùn)行的任務(wù)數(shù)量
調(diào)度次數(shù):調(diào)度中心所觸發(fā)的調(diào)度次數(shù)
執(zhí)行器數(shù)量:在整個(gè)調(diào)度中心中,在線的執(zhí)行器數(shù)量有多少
第五步 開始跟項(xiàng)目代碼整合:
pom.xml依賴引入
<xxl-job.version>2.2.0</xxl-job.version> <!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --> <dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>${xxl-job.version}</version> </dependency>
第六步 新增logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false" scan="true" scanPeriod="1 seconds"> <contextName>logback</contextName> <property name="log.path" value="./data/logs/xxl-job/app.log"/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern> </rollingPolicy> <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n </pattern> <root level="info"> <appender-ref ref="console"/> <appender-ref ref="file"/> </root> </configuration>
第七步 application.properties增加配置項(xiàng)
#----------xxl-job配置-------------- logging.config=classpath:logback.xml #調(diào)度中心部署地址,多個(gè)配置逗號(hào)分隔 "http://address01,http://address02" xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin #執(zhí)行器token,非空時(shí)啟用 xxl-job, access token。需要跟xxl-job-master服務(wù)中的同配置一模一樣 xxl.job.accessToken=xxxxx.net168 # 執(zhí)行器app名稱,和控制臺(tái)那邊配置一樣的名稱,不然注冊(cè)不上去 xxl.job.executor.appname=traffic-app-executor # [選填]執(zhí)行器注冊(cè):優(yōu)先使用該配置作為注冊(cè)地址,為空時(shí)使用內(nèi)嵌服務(wù) ”IP:PORT“ 作為注冊(cè)地址。 #從而更靈活的支持容器類型執(zhí)行器動(dòng)態(tài)IP和動(dòng)態(tài)映射端口問題。 xxl.job.executor.address= #[選填]執(zhí)行器IP :默認(rèn)為空表示自動(dòng)獲取IP(即springboot容器的ip和端口,可以自動(dòng)獲取,也可以指定),多網(wǎng)卡時(shí)可手動(dòng)設(shè)置指定IP,該IP不會(huì)綁定Host僅作為通訊實(shí)用;地址信息用于 "執(zhí)行器注冊(cè)" 和 "調(diào)度中心請(qǐng)求并觸發(fā)任務(wù)", xxl.job.executor.ip= # [選填]執(zhí)行器端口號(hào):小于等于0則自動(dòng)獲??;默認(rèn)端口為9999,單機(jī)部署多個(gè)執(zhí)行器時(shí),注意要配置不同執(zhí)行器端口; xxl.job.executor.port=9999 #執(zhí)行器日志文件存儲(chǔ)路徑,需要對(duì)該路徑擁有讀寫權(quán)限;為空則使用默認(rèn)路徑 xxl.job.executor.logpath=./data/logs/xxl-job/executor #執(zhí)行器日志保存天數(shù) xxl.job.executor.logretentiondays=30
配置圖解:
1.上述 配置xxl.job.accessToken=xxxxx.net168的值 和 xxl-job-2.2.0里面的配置xxl.job.accessToken的值需要一模一樣
2.xxl.job.executor.appname=traffic-app-executor 執(zhí)行器的名稱
需要跟調(diào)度中心執(zhí)行器名稱一模一樣,不然注冊(cè)不上去
properties配置加完后,需要增加一個(gè).java的配置讀取類:
package net.wnn.config; import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @Slf4j public class XxlJobConfig { @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.executor.appname}") private String appName; @Value("${xxl.job.executor.ip}") private String ip; @Value("${xxl.job.executor.port}") private int port; @Value("${xxl.job.accessToken}") private String accessToken; @Value("${xxl.job.executor.logpath}") private String logPath; @Value("${xxl.job.executor.logretentiondays}") private int logRetentionDays; @Bean public XxlJobSpringExecutor xxlJobSpringExecutor(){ log.info("》》》》》這是王姑娘的 xxl job 配置初始化 方法"); XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appName); xxlJobSpringExecutor.setIp(ip); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); xxlJobSpringExecutor.setLogPath(logPath); xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); return xxlJobSpringExecutor; } }
第八步 創(chuàng)建你的第一個(gè)XXL-Job分布式調(diào)度任務(wù)代碼:
package net.wnn.job; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; import net.wnn.service.TrafficService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @Slf4j public class TrafficJobHandler { @Autowired private TrafficService trafficService; /** * 過期流量包處理 * @param param * @return */ @XxlJob(value = "trafficExpiredHandler",init = "init",destroy = "destroy") public ReturnT<String> execute(String param){ log.info(" execute 任務(wù)方法觸發(fā)成功,刪除過期流量包"); return ReturnT.SUCCESS; } private void init(){ log.info(" MyJobHandler init >>>>>"); private void destroy(){ log.info(" MyJobHandler destroy >>>>>"); }
這步驟寫完之后,需要啟動(dòng)下應(yīng)用服務(wù),將IP地址注冊(cè)到xxl-job中,大概啟動(dòng)成功后30S才有。
第九步 :代碼寫完后,就需要進(jìn)入客戶端進(jìn)行相關(guān)參數(shù)的配置了
執(zhí)行器管理頁面:
到xxl-job調(diào)度中心里的執(zhí)行器管理->新增
第一步新增執(zhí)行器
Appname:是每一個(gè)執(zhí)行器的唯一表示AppName,執(zhí)行器會(huì)以周期性為appname進(jìn)行注冊(cè),為任務(wù)調(diào)度的時(shí)候使用
名稱:執(zhí)行器的名稱,因?yàn)閍ppname有限制字母與數(shù)字等等組成,可讀性不強(qiáng),這個(gè)名稱就是為了提高執(zhí)行器的可讀性
注冊(cè)方式:調(diào)度中心獲取執(zhí)行器地址的方式
自動(dòng)注冊(cè):執(zhí)行器自動(dòng)進(jìn)行執(zhí)行器的注冊(cè),通過底層的注冊(cè)表可以動(dòng)態(tài)的發(fā)現(xiàn)執(zhí)行器機(jī)器的地址
手動(dòng)錄入:人工手動(dòng)錄入執(zhí)行器的地址信息,多地址使用逗號(hào)進(jìn)行分割,供調(diào)度中心使用
機(jī)器地址:“注冊(cè)方式”為手動(dòng)錄入的時(shí)候才能使用,支持人工維護(hù)執(zhí)行器的地址
點(diǎn)擊保存后可能要等30S左右才回顯示機(jī)器的地址
第二步 新建任務(wù)管理:
其中JobHandler需要和代碼中的@xxljob value一模一樣
新建完任務(wù)后就惦記保存,然后再列表頁面的操作中下拉后選擇執(zhí)行一次:
選擇啟動(dòng)模式的話,就是按設(shè)定的cron表達(dá)式執(zhí)行: 上述任務(wù)設(shè)置的是一秒一次
調(diào)度成功日志:
運(yùn)行報(bào)表頁面:
到這分布式調(diào)度XXL-Job就整合完畢啦~
到此這篇關(guān)于分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作的文章就介紹到這了,更多相關(guān)Springboot2.X整合XXL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot集成XXL-JOB實(shí)現(xiàn)靈活控制的分片處理方案
- xxl-job定時(shí)任務(wù)配置應(yīng)用及添加到springboot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)API調(diào)用
- SpringBoot集成xxl-job實(shí)現(xiàn)超牛的定時(shí)任務(wù)的步驟詳解
- SpringBoot部署xxl-job方法詳細(xì)講解
- springboot整合xxl-job實(shí)現(xiàn)分布式定時(shí)任務(wù)的過程
- SpringBoot整合Xxl-job實(shí)現(xiàn)定時(shí)任務(wù)的全過程
- SpringBoot整合Xxl-Job的完整步驟記錄
- springboot整合 xxl-job及使用步驟
相關(guān)文章
Java實(shí)戰(zhàn)練習(xí)之撲克牌魔術(shù)
這篇文章主要介紹了Java實(shí)戰(zhàn)練習(xí)之撲克牌魔術(shù),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-04-04Java實(shí)現(xiàn)線程按序交替執(zhí)行的方法詳解
這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)線程按序交替執(zhí)行,文中的示例代碼講解詳細(xì),對(duì)我們了解線程有一定幫助,需要的可以參考一下2022-10-10Javabean轉(zhuǎn)換成json字符并首字母大寫代碼實(shí)例
這篇文章主要介紹了javabean轉(zhuǎn)成json字符并首字母大寫代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02java數(shù)據(jù)結(jié)構(gòu)之希爾排序
這篇文章主要為大家詳細(xì)介紹了java數(shù)據(jù)結(jié)構(gòu)之希爾排序的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11Springboot中@Transactional注解與異常處理機(jī)制方式
這篇文章主要介紹了Springboot中@Transactional注解與異常處理機(jī)制方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08