【開發經驗】分佈式任務調度——xxl-job

​ 之前瞭解了本地任務的調度方式,但是隨着定時任務的越來越多,越來越複雜,單機壓力壓力越來越大,所以任務服務也需要做高可用。如果部署多臺服務,就會存在任務誰來執行或者一個重複執行的問題。

​ 現在可以實現分佈式任務調度的框架有很多,xxl-jobquartz等等。

​ quartz分佈式任務調度是通過數據庫鎖實現的,實現思路簡單,但是功能也簡單,好多東西都需要自己二次開發。重點是需要簡單的二次開發,而且沒有可視化。

​ xxl-job上手很容器,有非常友好的可視化頁面,功能強大,1分鐘即可上手。至於如何解決服務高可用呢?如何解決重複執行問題呢?下面看。
在這裏插入圖片描述

1.xxl-job快速啓動

  1. 下載源碼:https://github.com/xuxueli/xxl-job
  2. 新建mysql數據庫,初始化表結構,表信息在源碼的doc/db/tables_xxl_job.sql目錄下。在這裏插入圖片描述
  3. 下載源碼後修改xxl-job-admin中的數據庫配置。在這裏插入圖片描述
  4. 通過spring boot的方式啓動即可。
  5. 瀏覽器通過http://localhost:8080/xxl-job-admin/進入登錄頁面,賬號密碼admin/123456

至此啓動成功。進入可視化頁面隨便點點很簡單的。

2.xxl-job基本使用

​ xxl-job可以分問調度中心執行器服務調度中心充當一個註冊中心的作用,任務的執行信息通過調度中心寫入到數據庫中,執行器服務啓動成功之後會再調度中心進行註冊。調度中心通過http請求調用執行器服務的接口進行任務的調度,執行器執行成功之後返回成功信息給調度信息。

在這裏插入圖片描述在這裏插入圖片描述

路由策略選擇:
FIRST(第一個):固定選擇第一個機器;
LAST(最後一個):固定選擇最後一個機器;
ROUND(輪詢):;
RANDOM(隨機):隨機選擇在線的機器;
CONSISTENT_HASH(一致性HASH):每個任務按照Hash算法固定選擇某一臺機器,且所有任務均勻散列在不同機器上。
LEAST_FREQUENTLY_USED(最不經常使用):使用頻率最低的機器優先被選舉;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的機器優先被選舉;
FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定爲目標執行器併發起調度;
BUSYOVER(忙碌轉移):按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;
SHARDING_BROADCAST(分片廣播):廣播觸發對應集羣中所有機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;

這樣任務服務的高可用即可解決。

​ 到此可能就想,這樣所有的任務就到調度中心了呀,調度中心需不需要高可用呢?如果調度中心部署多個,會不會有重複調度的問題呢?

調度中心是支持集羣部署的。但是需要注意一些重點:

  • DB配置保持一致;
  • 集羣機器時鐘保持一致(單機集羣忽視);
  • 建議:推薦通過nginx爲調度中心集羣做負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操作均通過該域名進行。

​ 基於數據庫的集羣方案,數據庫選用Mysql;集羣分佈式併發環境中進行定時任務調度時,會在各個節點會上報任務,存到數據庫中,執行時會從數據庫中取出觸發器來執行,如果觸發器的名稱和執行時間相同,則只有一個節點去執行此任務。

3.xxl-job特性

多種運行模式

​ xxl-job有調度中心,既然是一個調度中心,是不是可以不區分調度什麼任務,就到時候觸發事件就好啦?所以xxl-job有提供執行其他語言的運行模式。強不強!

GLUE模式(Java):任務以源碼方式維護在調度中心;該模式的任務實際上是一段繼承自IJobHandler的Java類代碼並 "groovy" 源碼方式維護,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器裏中的其他服務;
GLUE模式(Shell):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "shell" 腳本;
GLUE模式(Python):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "python" 腳本;
GLUE模式(PHP):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "php" 腳本;
GLUE模式(NodeJS):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "nodejs" 腳本;
GLUE模式(PowerShell):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "PowerShell" 腳本;

GLUE模式(Java)

quartz框架或者一些其他的任務調度框架都可以實現簡單的任務調度。但是xxl-job提供了更強大的特性。quartz使用的時候是服務中代碼已經加載好了,無法做到實時添加任務調度方法。

​ 此模式可以通過web IDE,在瀏覽器中添加java代碼進行執行。此功能超級變態,同時也超級危險。

​ 示例:

1.在執行器服務創建類UserService

package com.xxl.job.executor.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public String userName="張三";
}

創建成功之後啓動執行器服務。服務啓動成功UserService會被加載到spring IOC容器中。

2.創建任務

在這裏插入圖片描述

創建成功之後點即操作

在這裏插入圖片描述

進入頁面之後即可隨意編寫代碼,重點的是這裏的代碼是在數據庫中,執行的時候是在執行器服務執行的。wbe IDE中複製如下代碼,在調度器調度的時候即可輸出張三。這樣當然是很靈活,但是也很危險,如果調度器入口被別人獲取了,那就可以爲所欲爲了。

package com.xxl.job.service.handler;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxl.job.executor.service.UserService
public class LikuoJobHandler extends IJobHandler {

	@Autowired
  	private UserService userService;
	@Override
	public ReturnT<String> execute(String param) throws Exception {
		System.out.println(userService.userName);
		return ReturnT.SUCCESS;
	}

}

分片廣播

該特性適用場景如:

  • 1、分片任務場景:10個執行器的集羣來處理10w條數據,每臺機器只需要處理1w條數據,耗時降低10倍;
  • 2、廣播任務場景:廣播執行器機器運行shell腳本、廣播集羣節點進行緩存更新等

參考資料

官網文檔:https://www.xuxueli.com/xxl-job/

源碼地址:https://github.com/xuxueli/xxl-job

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