點擊關注公眾號,實用技術文章及時了解
定時任務是按照指定時間周期運行任務。使用場景為在某個固定時間點執行,或者周期性的去執行某個任務,比如:每天晚上24點做數據匯總,定時發送短信等。
1.2.常見定時任務方案上述的定時任務都是集中式(單體項目使用)的定時任務,在分布式中將會面臨一些問題或不足
XXL-JOB是一個分布式任務調度平台,於2015問世,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。其具備且不止如下能力
具體見: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工具導入項目
源碼倉庫地址
項目代碼結構如下

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

數據庫如下

打開 xxl-job-admin 的配置文件,/xxl-job/xxl-job-admin/src/main/resources/application.properties 對調度中心進行配置,重要配置如下
下面根據自己的情況進行修改,不要直接複製
###調度中心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」, 登錄後運行界面如下圖所示。

「執行器」項目:xxl-job-executor-sample-springboot (提供多種版本執行器供選擇,現以 springboot 版本為例,可直接使用,也可以參考其並將現有項目改造成執行器)
作用:負責接收「調度中心」的調度並執行;可直接部署執行器,也可以將執行器集成到現有業務項目中。
修改配置:/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties
上面配置是為了在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,可以直接配置實用,如下:
【重要】 如果我們要寫自己的定時任務,參照上面方法,在方法上註解一個@XxlJob("任務名字") ,方法可以接受一個字符串參數,方法需要返回ReturnT格式。
最後啟動執行器項目.
3.配置定時任務3.1.執行器創建打開調度中心可視化界面,在執行器管理界面,添加新增執行器

appName : 執行器的名字,可以任意填寫
名稱:任意填寫
註冊方式:調度中心是通過RPC的方式對執行器發起調度,所以這裡需要的是執行器項目的ip:port ,注意,該端口不是執行器項目的server.port ,而是:xxl.job.executor.port 端口。你可以選擇自動註冊,也可以手動錄入。
在 任務管理 界面,新增任務

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

調度日誌

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注入執行器里中的其他服務),比如我的定時任務如下,編輯好之後點擊保存

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

調度中心支持集群部署,提升調度系統容災和可用性。調度中心集群部署時,幾點要求和建議:
但是建議:推薦通過nginx為調度中心集群做負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操作均通過該域名進行。
1.2.啟動多個調度中心修改調度中心端口,啟動多個調度中心,我這裡啟動兩個如
當啟動多個調度器時,執行器配置調度中心部署跟地址可以用逗號分隔。執行器將會使用該地址進行「執行器心跳註冊」和「任務結果回調」;為空則關閉自動註冊;
但是建議:推薦通過nginx為調度中心集群做負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操作均通過該域名進行。
我們啟動了2個調度中心,那麼我的執行器項目該註冊到哪個調度中心呢?我們通過Nginx來解決這個問題,原理如下圖:

我們再hosts配置 www.jobs.com作為nginx的主機域名,然後反向代理到多個調度中心,這樣一來執行器就只需要註冊到www.jobs.com Nginx即可。
修改 C:\Windows\System32\drivers\etc\hosts增加配置如下
127.0.0.1www.jobs.comNginx配置如下
#調度中心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-executor-sample-springboot配置文件application.properties
第一個實例配置
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中配置,允許啟動多個實例

啟動實例如下

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

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

xxl-job確實很強大,功能也很全,經過該文章學習相信你可以把xxl-job給用起來了,但是如果你的項目是一個小體量的單體,我不太建議使用它,Quzrtz或者SpringBoot Task就足夠 ,對於xxl-job個人還是有些笨重。
推薦
Java面試題寶典
技術內卷群,一起來學習!!
PS:因為公眾號平台更改了推送規則,如果不想錯過內容,記得讀完點一下「在看」,加個「星標」,這樣每次新文章推送才會第一時間出現在你的訂閱列表里。點「在看」支持我們吧!