XXL-JOB是一個分佈式任務調度平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。它的有兩個核心模塊,一個模塊叫作調度中心,另一個模塊叫作執行器,它把任務調度和任務執行分紅兩個部分。這樣調度模塊只須要負責任務的調度屬性,觸發調度信號。執行模塊只須要接收調度信號,去執行具體的業務邏輯,二者能夠各自的進行擴容和縮容。圖1是一張來自官方的架構圖。php
既然是一個分佈式調度平臺,確定會有一個調度中心,固然執行器(被調度者)也是必不可少的,能夠參考架構圖。因此,使用xxl-job搭建一個demo,也必須有兩個端,下面本文分別從準備工做、搭建「調度中心」、搭建「執行器」三個部分進行說明。java
源碼地址:https://github.com/xuxueli/xxl-jobnode
我使用的源碼是2.2.0版本,這是目前最新的release版本。python
源碼包含了文檔(數據庫初始化腳本、官方文檔、架構圖等)、調度中心源碼、核心core、各個版本的執行器源碼。如圖2所示:mysql
2.1.2 數據庫準備
數據庫腳本在doc路徑下,將其執行以後能夠建立一個數據庫,如圖3所示:git
將數據庫鏈接信息和報警信息配置成本身的,配置文件以下:github
### web server.port=8080 server.servlet.context-path=/xxl-job-admin ### actuator management.server.servlet.context-path=/actuator management.health.mail.enabled=false ### resources spring.mvc.servlet.load-on-startup=0 spring.mvc.static-path-pattern=/static/** spring.resources.static-locations=classpath:/static/ ### freemarker spring.freemarker.templateLoaderPath=classpath:/templates/ spring.freemarker.suffix=.ftl spring.freemarker.charset=UTF-8 spring.freemarker.request-context-attribute=request spring.freemarker.settings.number_format=0.########## ### mybatis mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml #mybatis.type-aliases-package=com.xxl.job.admin.core.model ### xxl-job, datasource spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ### datasource-pool spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=10 spring.datasource.hikari.maximum-pool-size=30 spring.datasource.hikari.auto-commit=true spring.datasource.hikari.idle-timeout=30000 spring.datasource.hikari.pool-name=HikariCP spring.datasource.hikari.max-lifetime=900000 spring.datasource.hikari.connection-timeout=10000 spring.datasource.hikari.connection-test-query=SELECT 1 ### xxl-job, email spring.mail.host=smtp.qq.com spring.mail.port=25 spring.mail.username=xxx@qq.com spring.mail.password=xxx spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory ### xxl-job, access token xxl.job.accessToken= ### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en") xxl.job.i18n=zh_CN ## xxl-job, triggerpool max size xxl.job.triggerpool.fast.max=200 xxl.job.triggerpool.slow.max=100 ### xxl-job, log retention days xxl.job.logretentiondays=30
在IDEA裏面直接運行,若是使用的是macOS系統的話,可能會出現錯誤:Failed to create parent directories for [/data/applogs/xxl-job/xxl-job-admin.log],如圖4所示:web
解決辦法是:將logback.xml中的「/data/applogs/xxl-job/xxl-job-admin.log」改成「./data/applogs/xxl-job/xxl-job-admin.log」,如圖5所示。後續在測試運行的時候,執行器端會拋出相似異常,用一樣的方式能夠解決。算法
啓動以後瀏覽器訪問http://localhost:8080/xxl-job-admin,使用默認的用戶名(admin)和密碼(123456)登錄以後,能夠看到如圖6所示頁面:spring
使用IDEA新建一個Spring Boot項目:xxl-job-executor
Maven依賴:
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.2.0</version> </dependency>
主要須要配置xxl-job的調度中心地址信息、xxl-job執行器相關信息。配置文件以下:
# web port server.port=8081 # no web #spring.main.web-environment=false # log config logging.config=classpath:logback.xml ### xxl-job admin address list, such as "http://address" or "http://address01,http://address02" xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin ### xxl-job, access token xxl.job.accessToken= ### xxl-job executor appname xxl.job.executor.appname=xxl-job-executor-test ### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null xxl.job.executor.address= ### xxl-job executor server-info xxl.job.executor.ip= xxl.job.executor.port=9999 ### xxl-job executor log-path xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler ### xxl-job executor log-retention-days xxl.job.executor.logretentiondays=30
還要建立一個XxlJobConfig.java配置執行器。代碼以下:
@Configuration public class XxlJobConfig { private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.accessToken}") private String accessToken; @Value("${xxl.job.executor.appname}") private String appname; @Value("${xxl.job.executor.address}") private String address; @Value("${xxl.job.executor.ip}") private String ip; @Value("${xxl.job.executor.port}") private int port; @Value("${xxl.job.executor.logpath}") private String logPath; @Value("${xxl.job.executor.logretentiondays}") private int logRetentionDays; @Bean public XxlJobSpringExecutor xxlJobExecutor() { logger.info(">>>>>>>>>>> xxl-job config init."); XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appname); xxlJobSpringExecutor.setAddress(address); xxlJobSpringExecutor.setIp(ip); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); xxlJobSpringExecutor.setLogPath(logPath); xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); return xxlJobSpringExecutor; } }
固然還要添加logback.xml文件。
代碼以下:
@Component public class TestXxlJobHandler { private static Logger logger = LoggerFactory.getLogger(TestXxlJobHandler.class); /** * 一、簡單任務示例(Bean模式) */ @XxlJob("testJobHandler") public ReturnT<String> demoJobHandler(String param) throws Exception { System.out.println(new Date() + "Test Xxl-Job~"); return ReturnT.SUCCESS; } }
完成以後的整個代碼結構如圖8所示:
在本機運行調度中心和執行器。
在調度中心新增一個測試執行器,AppName爲xxl-job-executor-test,名稱爲測試執行器,註冊方式選擇自行註冊便可,如圖9所示:
新增一個任務,名稱與代碼中名稱一致,配置爲每2分鐘執行一次,路由策略爲一致性HASH,運行模式爲BEAN,阻塞處理策略爲單機串行,配置如圖10所示:
詳細配置屬性能夠參考:
● 執行器:任務的綁定的執行器,任務觸發調度時將會自動發現註冊成功的執行器, 實現任務自動發現功能; 另外一方面也能夠方便的進行任務分組。每一個任務必須綁定一個執行器, 可在 "執行器管理" 進行設置;
● 任務描述:任務的描述信息,便於任務管理;
● 路由策略:當執行器集羣部署時,提供豐富的路由策略,包括;
FIRST(第一個):固定選擇第一個機器;
LAST(最後一個):固定選擇最後一個機器;
ROUND(輪詢):;
RANDOM(隨機):隨機選擇在線的機器;
CONSISTENT_HASH(一致性HASH):每一個任務按照Hash算法固定選擇某一臺機器,且全部任務均勻散列在不一樣機器上。
LEAST_FREQUENTLY_USED(最不常用):使用頻率最低的機器優先被選舉;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的機器優先被選舉;
FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定爲目標執行器併發起調度;
BUSYOVER(忙碌轉移):按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;
SHARDING_BROADCAST(分片廣播):廣播觸發對應集羣中全部機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;
● Cron:觸發任務執行的Cron表達式;
● 運行模式:
BEAN模式:任務以JobHandler方式維護在執行器端;須要結合 "JobHandler" 屬性匹配執行器中任務;
GLUE模式(Java):任務以源碼方式維護在調度中心;該模式的任務其實是一段繼承自IJobHandler的Java類代碼並 "groovy" 源碼方式維護,它在執行器項目中運行,可以使用@Resource/@Autowire注入執行器裏中的其餘服務;
GLUE模式(Shell):任務以源碼方式維護在調度中心;該模式的任務其實是一段 "shell" 腳本;
GLUE模式(Python):任務以源碼方式維護在調度中心;該模式的任務其實是一段 "python" 腳本;
GLUE模式(PHP):任務以源碼方式維護在調度中心;該模式的任務其實是一段 "php" 腳本;
GLUE模式(NodeJS):任務以源碼方式維護在調度中心;該模式的任務其實是一段 "nodejs" 腳本;
GLUE模式(PowerShell):任務以源碼方式維護在調度中心;該模式的任務其實是一段 "PowerShell" 腳本;
● JobHandler:運行模式爲 "BEAN模式" 時生效,對應執行器中新開發的JobHandler類「@JobHandler」註解自定義的value值;
● 阻塞處理策略:調度過於密集執行器來不及處理時的處理策略;
單機串行(默認):調度請求進入單機執行器後,調度請求進入FIFO隊列並以串行方式運行;
丟棄後續調度:調度請求進入單機執行器後,發現執行器存在運行的調度任務,本次請求將會被丟棄並標記爲失敗;
覆蓋以前調度:調度請求進入單機執行器後,發現執行器存在運行的調度任務,將會終止運行中的調度任務並清空隊列,而後運行本地調度任務;
● 子任務:每一個任務都擁有一個惟一的任務ID(任務ID能夠從任務列表獲取),當本任務執行結束而且執行成功時,將會觸發子任務ID所對應的任務的一次主動調度。
● 任務超時時間:支持自定義任務超時時間,任務運行超時將會主動中斷任務;
● 失敗重試次數;支持自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試;
● 報警郵件:任務調度失敗時郵件通知的郵箱地址,支持配置多郵箱地址,配置多個郵箱地址時用逗號分隔;
● 負責人:任務的負責人;
● 執行參數:任務執行所需的參數;
啓動調度任務,如圖11所示:
能夠查看日誌或者控制檯信息,運行結果滿意,如圖12所示:
在控制檯運行報表界面也能夠看到調度和執行狀況,如圖13所示。圖中那一次調度失敗是因爲執行器重啓,形成了調度中心調度任務的時候發現調度地址爲空,因此執行失敗。
參考文檔:官方中文文檔