1. 程式人生 > >分散式任務排程平臺XXL-JOB快速搭建教程

分散式任務排程平臺XXL-JOB快速搭建教程

# 1. XXL-JOB簡介 XXL-JOB是一個分散式任務排程平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴充套件。現已開放原始碼並接入多家公司線上產品線,開箱即用。它的有兩個核心模組,一個模組叫做排程中心,另外一個模組叫做執行器,它把任務排程和任務執行分成兩個部分。這樣排程模組只需要負責任務的排程屬性,觸發排程訊號。執行模組只需要接收排程訊號,去執行具體的業務邏輯,兩者可以各自的進行擴容和縮容。圖1是一張來自官方的架構圖。 ![圖1 xxl-job v2.1.0架構圖](https://upload-images.jianshu.io/upload_images/6842240-193790d80cfe65fa?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 2. XXL-JOB搭建 既然是一個分散式排程平臺,肯定會有一個排程中心,當然執行器(被排程者)也是必不可少的,可以參考架構圖。所以,使用xxl-job搭建一個demo,也必須有兩個端,下面本文分別從準備工作、搭建“排程中心”、搭建“執行器”三個部分進行說明。 ## 2.1 準備工作 ### 2.1.1 下載原始碼 原始碼地址:[https://github.com/xuxueli/xxl-job](https://github.com/xuxueli/xxl-job) 我使用的原始碼是2.2.0版本,這是目前最新的release版本。 原始碼包含了文件(資料庫初始化指令碼、官方文件、架構圖等)、排程中心原始碼、核心core、各個版本的執行器原始碼。如圖2所示: ![圖2 原始碼結構](https://upload-images.jianshu.io/upload_images/6842240-f6a7f322efa58994?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2.1.2 資料庫準備 資料庫指令碼在doc路徑下,將其執行之後可以建立一個數據庫,如圖3所示: ![圖3 資料庫](https://upload-images.jianshu.io/upload_images/6842240-1013073e64a3ac77?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 2.2 搭建排程中心 ### 2.2.1 配置排程中心 將資料庫連線資訊和報警資訊配置成自己的,配置檔案如下: ``` ### 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 [email protected] 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 ``` ### 2.2.2 啟動排程中心 在IDEA裡面直接執行,如果使用的是macOS系統的話,可能會出現錯誤:Failed to create parent directories for [/data/applogs/xxl-job/xxl-job-admin.log],如圖4所示: ![圖4 錯誤資訊提示](https://upload-images.jianshu.io/upload_images/6842240-91af28d685886a12?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 解決辦法是:將logback.xml中的“/data/applogs/xxl-job/xxl-job-admin.log”改為“./data/applogs/xxl-job/xxl-job-admin.log”,如圖5所示。後續在測試執行的時候,執行器端會丟擲類似異常,用同樣的方式可以解決。 ![圖5 修改logback.xml](https://upload-images.jianshu.io/upload_images/6842240-771ea716743284c2?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 啟動之後瀏覽器訪問http://localhost:8080/xxl-job-admin,使用預設的使用者名稱(admin)和密碼(123456)登陸之後,可以看到如圖6所示頁面: ![圖6 排程中心頁面](https://upload-images.jianshu.io/upload_images/6842240-ca8ef1cd58562a42?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 2.3 搭建“執行器” ### 2.3.1 新建執行器專案 使用IDEA新建一個Spring Boot專案:xxl-job-executor ![圖7 新建Spring Boot專案](https://upload-images.jianshu.io/upload_images/6842240-fdce723cb0d58f0e?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 2.3.2 新增相關依賴和配置執行器 Maven依賴: ``` com.xuxueli xxl-job-core 2.2.0 ``` 主要需要配置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檔案。 ### 2.3.3 編寫執行器 1. 在Spring Bean例項中,開發Job方法,方式格式要求為 "public ReturnT execute(String param)" 2. 為Job方法添加註解 "@XxlJob(value="自定義jobhandler名稱", init = "JobHandler初始化方法", destroy = "JobHandler銷燬方法")",註解value值對應的是排程中心新建任務的JobHandler屬性的值。之前的2.1.0版本中不支援在方法上面添加註解,需要在類上面新增@JobHandler註解,並繼承IJobHandler。 3. 執行日誌:需要通過 "XxlJobLogger.log" 列印執行日誌; 程式碼如下: ``` @Component public class TestXxlJobHandler { private static Logger logger = LoggerFactory.getLogger(TestXxlJobHandler.class); /** * 1、簡單任務示例(Bean模式) */ @XxlJob("testJobHandler") public ReturnT demoJobHandler(String param) throws Exception { System.out.println(new Date() + "Test Xxl-Job~"); return ReturnT.SUCCESS; } } ``` 完成之後的整個程式碼結構如圖8所示: ![圖8 執行器程式碼結構](https://upload-images.jianshu.io/upload_images/6842240-61572d02ffc6e749?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 3. 測試 在本機執行排程中心和執行器。 ## 3.1 新增執行器 在排程中心新增一個測試執行器,AppName為xxl-job-executor-test,名稱為測試執行器,註冊方式選擇自行註冊即可,如圖9所示: ![圖9 新增執行器](https://upload-images.jianshu.io/upload_images/6842240-10bf23a6d4f0beba?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 3.2 新增任務 ### 3.2.1 新增任務 新增一個任務,名稱與程式碼中名稱一致,配置為每2分鐘執行一次,路由策略為一致性HASH,執行模式為BEAN,阻塞處理策略為單機序列,配置如圖10所示: ![圖10 新增任務](https://upload-images.jianshu.io/upload_images/6842240-f5d4743a8954447d?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 3.2.2 配置屬性 詳細配置屬性可以參考: ● 執行器:任務的繫結的執行器,任務觸發排程時將會自動發現註冊成功的執行器, 實現任務自動發現功能; 另一方面也可以方便的進行任務分組。每個任務必須繫結一個執行器, 可在 "執行器管理" 進行設定; ● 任務描述:任務的描述資訊,便於任務管理; ● 路由策略:當執行器叢集部署時,提供豐富的路由策略,包括; 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所對應的任務的一次主動排程。 ● 任務超時時間:支援自定義任務超時時間,任務執行超時將會主動中斷任務; ● 失敗重試次數;支援自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試; ● 報警郵件:任務排程失敗時郵件通知的郵箱地址,支援配置多郵箱地址,配置多個郵箱地址時用逗號分隔; ● 負責人:任務的負責人; ● 執行引數:任務執行所需的引數; ## 3.3 啟動任務測試 啟動排程任務,如圖11所示: ![圖11 啟動排程](https://upload-images.jianshu.io/upload_images/6842240-85d0954cc027fad4?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 可以檢視日誌或者控制檯資訊,執行結果滿意,如圖12所示: ![圖12 執行結果](https://upload-images.jianshu.io/upload_images/6842240-399c79d966f30159?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 在控制檯執行報表介面也可以看到排程和執行情況,如圖13所示。圖中那一次排程失敗是由於執行器重啟,造成了排程中心排程任務的時候發現排程地址為空,所以執行失敗。 ![圖13 執行報表](https://upload-images.jianshu.io/upload_images/6842240-f9bd5b11ab0c7444?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 參考文件:[官方中文文件](https://www.xuxueli.com/xx