Spring Boot 整合定時任務,可以動態編輯的定時任務!

定時任務,松哥之前寫過多篇文章和大家介紹,上次還自己 DIY 了一個可以動態編輯的定時任務,還錄了一個配套視頻:

相關的資料鏈接戳這裏:

  1. Spring 定時任務玩出花!
  2. 手把手教你定製可編輯的定時任務!
  3. 開發可配置的定時任務~第二彈
  4. Vue非典型用法,一個簡單的管理頁面

不過我們當時自己寫的這個不支持分佈式環境,想要支持倒也不是啥難事,弄一個 zookeeper 或者 redis 作爲公共的信息中心,裏邊記錄了定時任務的各種運行情況,有了這個就能支持分佈式環境了。

今天咱們不自己寫了,我們來看一個現成的框架:ElasticJob,有一個跟他齊名的 xxljob,這個咱們以後再抽空介紹。

1. ElasticJob

1.1 簡介

ElasticJob 是一個分佈式作業調度解決方案,它的官網是:

Elastic Job 的前身是由噹噹開源的一款分佈式任務調度框架 dd-job,不過在 2020 年 5 月 28 日加入到了 Apache 基金會,成爲 Apache 下的一個開源項目:

ElasticJob 通過彈性調度、資源管控、以及作業治理的功能,打造一個適用於互聯網場景的分佈式調度解決方案,並通過開放的架構設計,提供多元化的作業生態。

使用 ElasticJob 能夠讓開發工程師不再擔心任務的線性吞吐量提升等非功能需求,使他們能夠更加專注於面向業務編碼設計;同時,它也能夠解放運維工程師,使他們不必再擔心任務的可用性和相關管理需求,只通過輕鬆的增加服務節點即可達到自動化運維的目的。

ElasticJob 是面向互聯網生態和海量任務的分佈式調度解決方案,由兩個相互獨立的子項目 ElasticJob-LiteElasticJob-Cloud 組成。

其中 ElasticJob-Lite 定位爲輕量級無中心化解決方案,使用 jar 的形式提供分佈式任務的協調服務:

ElasticJob-Cloud 則採用自研 Mesos Framework 的解決方案,額外提供資源治理、應用分發以及進程隔離等功能:

ElasticJob-Lite VS ElasticJob-Cloud

ElasticJob-Lite ElasticJob-Cloud
無中心化
資源分配 不支持 支持
作業模式 常駐 常駐 + 瞬時
部署依賴 ZooKeeper ZooKeeper + Mesos

它的各個產品使用統一的作業 API,開發者僅需一次開發,即可隨意部署(即 ElasticJob-LiteElasticJob-Cloud 使用相同的 API,主要是部署方式不同而已)。

1.2 功能列表

  • 彈性調度

    • 支持任務在分佈式場景下的分片和高可用
    • 能夠水平擴展任務的吞吐量和執行效率
    • 任務處理能力隨資源配備彈性伸縮
  • 資源分配

    • 在適合的時間將適合的資源分配給任務並使其生效
    • 相同任務聚合至相同的執行器統一處理
    • 動態調配追加資源至新分配的任務
  • 作業治理

    • 失效轉移
    • 錯過作業重新執行
    • 自診斷修復
  • 作業依賴(TODO)

    • 基於有向無環圖(DAG)的作業間依賴
    • 基於有向無環圖(DAG)的作業分片間依賴
  • 作業開放生態

    • 可擴展的作業類型統一接口
    • 豐富的作業類型庫,如數據流、腳本、HTTP、文件、大數據等
    • 易於對接業務作業,能夠與 Spring 依賴注入無縫整合
  • 可視化運維平臺(https://github.com/apache/shardingsphere-elasticjob-ui)

    • 作業管控端
    • 作業執行歷史數據追蹤
    • 註冊中心管理

2. 實踐

說了這麼多,接下來我們通過一個簡單的案例來體驗一把 ElasticJob 吧。畢竟有代碼,感覺更真實。

首先我們創建一個 Spring Boot 工程,引入 Web 依賴:

然後手動加入 ElasticJob 的 starter:

<dependency>
    <groupid>org.apache.shardingsphere.elasticjob</groupid>
    <artifactid>elasticjob-lite-spring-boot-starter</artifactid>
    <version>3.0.1</version>
</dependency>

接下來我們創建一個作業,作業有幾種不同的創建方式,我們先來看一種基於實現 SimpleJob 接口創建的作業:

/**
 * @author 江南一點雨
 * @微信公衆號 江南一點雨
 * @網站 http://www.itboyhub.com
 * @國際站 http://www.javaboy.org
 * @微信 a_java_boy
 * @GitHub https://github.com/lenve
 * @Gitee https://gitee.com/lenve
 */
@Component
public class MyFirstJob implements SimpleJob {
private static final Logger logger = LoggerFactory.getLogger(MyFirstJob.class);
    @Override
    public void execute(ShardingContext shardingContext) {
        logger.info("作業名稱:{};作業參數:{};分片總數:{};當前分片:{};分片參數:{};任務編號:{}",shardingContext.getJobName(),shardingContext.getJobParameter(),shardingContext.getShardingTotalCount(),shardingContext.getShardingItem(),shardingContext.getShardingParameter(),shardingContext.getTaskId());
    }
}

當定時任務執行的時候,execute 方法會被觸發,其中參數 ShardingContext 中保存着定時任務相關的參數,這些參數都是我們在 application.properties 中配置的,我們繼續來看:

elasticjob.reg-center.server-lists=zoo1:2181,zoo2:2182,zoo3:2183
elasticjob.reg-center.namespace=javaboy

elasticjob.jobs.my-first-job.elastic-job-class=org.javaboy.elasticjob.job.MyFirstJob
elasticjob.jobs.my-first-job.cron=0/3 * * * * ?
elasticjob.jobs.my-first-job.sharding-total-count=1
elasticjob.jobs.my-first-job.overwrite=true
elasticjob.jobs.my-first-job.job-parameter=hello javaboy!
elasticjob.jobs.my-first-job.sharding-item-parameters=0=A,1=B,2=C

這裏的配置分爲兩大類:

  • 註冊中心配置
  • 定時任務配置

使用 ElasticJob 需要註冊中心 zookeeper,這個也好理解,因爲 ElasticJob 支持任務在分佈式場景下的分片和高可用,所以必然需要一個調度中心,這個 zk 就是調度中心。我這裏開啓了一個 zk 集羣,裏邊有三個實例,三個 zk 地址之間用 , 隔開。同時我們還要配置一個 namespace,這個 namespace 的作用是防止不同應用的定時任務衝突了,我們給每個應用取一個不同於其他應用的 namespace,這樣就不用擔心衝突了。

接下來是配置作業。

配置作業的前綴統一是 elasticjob.jobs,緊接着就是作業的名稱,這個作業名稱可以隨意配置,但是最好能一眼看出來是哪個作業,MyFirstJob#execute 方法中的 shardingContext.getJobName() 獲取到的就是這個值。

我們這裏一共配置了六個屬性,我來一一解釋下:

  • elastic-job-class:作業的全路徑。
  • cron:cron 表達式。
  • sharding-total-count:分片的總數,即有幾個實例執行當前定時任務,MyFirstJob#execute 方法中的 shardingContext.getShardingTotalCount() 獲取到的就是這個值。
  • overwrite:是否每次啓動的時候覆蓋之前的配置,如果設置爲 false,則如果修改了 cron 表達式等,重啓之後不會生效。
  • job-parameter:作業的參數,MyFirstJob#execute 方法中的 shardingContext.getJobParameter() 獲取到的就是這個值。
  • sharding-item-parameters:分片的參數,0、1、2 分別表示第幾個分片,MyFirstJob#execute 方法中的 shardingContext.getShardingParameter() 獲取到的就是這個值。

好啦,現在就配置完成了。

3. 運行

現在我們直接啓動 Spring Boot 項目,啓動之後,控制檯就會打印如下日誌:

沒問題,每隔三秒鐘打印一次日誌。

現在我們再次啓動一個當前項目的實例,勾選 Allow parallel run 就可以啓動多個實例(啓動新實例時記得修改端口號):

當新的實例啓動之後,我們發現第一次啓動的實例中已經沒有打印日誌了,轉而在第二次啓動的實例中打印日誌,這就是因爲我們配置的 sharding-total-count 爲 1,即同一時間只有一個實例中的定時任務在運行。

3. 運維平臺

ElasticJob 提供了一個運維平臺,可以通過這個平臺來動態管理定時任務,運維平臺地址:

運維平臺使用步驟:

  1. 克隆項目下來:git clone https://github.com/apache/shardingsphere-elasticjob-ui.git
  2. 進入到目錄中:cd shardingsphere-elasticjob-ui
  3. 打包:mvn clean package -Prelease
  4. 打包完成後,解壓 shardingsphere-elasticjob-ui/shardingsphere-elasticjob-ui-distribution/shardingsphere-elasticjob-lite-ui-bin-distribution/target/apache-shardingsphere-elasticjob-3.1.0-SNAPSHOT-lite-ui-bin.tar.gz 文件,然後執行其 bin 目錄下的 startup.sh 腳本啓動。

上面第三步打包,由於網絡原因很容易出錯,所以小夥伴們要是打包失敗,可以在公衆號江南一點雨後臺回覆 shardingsphere-elasticjob-ui,獲取松哥打包好的文件。

運維平臺啓動之後,瀏覽器輸入 http://localhost:8088 就會跳轉到登錄頁面,如下:

默認的用戶名密碼都是 root。

註冊成功之後,先點擊註冊中心配置,然後選擇添加按鈕,先來添加註冊中心,添加完註冊中心之後,這個運維平臺會自動從註冊中心上讀取定時任務信息:

如實填寫就行了,注意命名空間千萬別寫錯了,寫成了其他的就讀取不到定時任務了。

接下來點擊連接按鈕,建立和 zk 之間的連接:

點擊作業維度,就可以查看作業的詳細信息,包括作業名稱、分片總數、cron 表達式等:

最後面有四個操作按鈕:

  • 修改:修改作業的詳細信息,例如修改作業的 cron 表達式。
  • 詳情:查看作業的詳細信息。
  • 觸發:觸發作業的執行。
  • 失效:相當於暫停作業的執行,點擊失效按鈕之後,會出現生效按鈕,點擊生效按鈕,作業可以生效繼續執行。
  • 終止:停止該作業。

點擊服務器維度,可以查看服務器信息:

4. 小結

好啦,今天就通過一個簡單的案例,和小夥伴們展示了一下 ElasticJob 的玩法,關於 ElasticJob 的其他玩法,咱們後面有空繼續聊~

本文案例下載地址:https://github.com/lenve/javaboy-code-samples

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章