我寫了一個教學型的任務調度系統,很強!
一、架構概覽
在我的職業生涯里,接觸過如下 TimerTask 、Quartz 、SpringTask、 時間輪 HashWheelTimer 、Elastic-Job 、XXL-JOB、PowerJob、AirFlow 等任務調度系統,也曾在一家汽車租賃公司自研過基于 XXL-JOB 改造的任務調度系統。
不少同學對我原來的自研經歷很感興趣,于是我編寫了一個教學型的任務調度系統(支持 10萬 + 調度任務),希望能幫助中高級工程師快速提升架構思維。
經過多輪思考,最終架構圖如下 :
圖片
任務調度系統分為三個核心組件:
1、網關層負責應用的接入,任務的推送。
2、Admin 層負責任務的管理、任務的分片、UI 界面等。
3、Worker 層負責任務的調度,并將任務觸發到網關。
之所以這么設計,必須保證所有的組件是可水平擴展的 。
技術棧如下表:
技術名稱 | 簡介 |
Spring Boot | 基于 Spring 的快速開發框架,簡化配置,提供內嵌服務器和自動配置功能。 |
MySQL | 開源關系型數據庫,支持 SQL 和事務,適用于結構化數據存儲與管理。 |
MyBatis | 半自動化 ORM 框架,通過 XML/注解靈活映射 SQL 與 Java 對象,支持動態 SQL。 |
RocksDB | 高性能嵌入式 Key-Value 存儲引擎,適用于高吞吐、低延遲的本地數據持久化場景。 |
Netty | 異步事件驅動網絡框架,支持高并發通信,常用于構建 TCP/UDP/HTTP 協議服務端或客戶端。 |
Guava | Google 開發的 Java 核心工具庫,提供集合、緩存、字符串處理等高效工具類,簡化開發。 |
Quartz | 開源作業調度框架,支持復雜定時任務(如按計劃執行、周期性任務)。 |
Zookeeper | 開源分布式協調框架,提供分布式同步、配置管理和服務發現,常用于分布式系統中。 |
項目倉庫截圖:
圖片
二、部署流程
勇哥將服務部署到 1 臺阿里云服務器上,數據庫部署在騰訊云。
圖片
1 數據庫 MySQL 和 Zookeeper
- 數據庫
創建數據庫 platform_schedule ,執行 doc 目錄下的 SQL 腳本:
圖片
執行完成后,如下圖:
圖片
- Zookeeper
下載 zookeeper-3.6.0 版本,解壓后復制一份 zoo_sample.cfg ,重命名為 zoo.cfg ,保持默認配置即可。
圖片
2 部署 Admin、GateWay、Worker
- 打包
在 Admin 模塊、GateWay 模塊、Worker 模塊執行三個步驟:修改數據庫配置、打包、拷貝部署包到服務器。
圖片
- 啟動 Admin 服務
nohup java -Xms300m -Xmx350m -jar schedule-admin.jar &- 啟動 GateWay 服務
nohup java -Xms200m -Xmx400m -jar schedule-gateway.jar &- 啟動 Worker 服務
nohup java -Xms200m -Xmx300m -jar schedule-worker.jar &3.線上體驗
1)登錄
圖片
2)集群管理
圖片
因為 GateWay 、Woker 都需要向 Admin 注冊實例信息,我們可以將 Admin 當做簡單的注冊中心,所以需要配置如下信息:
- Admin 注冊服務地址 ,格式是:ip1:10001;ip2:10001。
- zk 集群地址 ,用于 Admin 集群,實現主從模式 。
3.添加應用
圖片
我們生產環境創建了1個應用,應用名是: mytest , appKey 為 1400001,客戶端訪問任務調度系統需要配置 appKey 和 appSecret 。
4.添加任務
圖片
我們定義了一個任務 ,名稱是:測試任務,每 15 秒執行一次,jobHandler 定義為 myJobHandler 。
5.測試任務
從 gitcode 下載源碼后 ,查看 Demo 模塊 ,模塊需要添加客戶端依賴和 編寫任務實現。
1)客戶端依賴
<!-- 依賴 客戶端 start -->
<dependency>
<groupId>cn.javayong</groupId>
<artifactId>schedule-client</artifactId>
<version>${parent.version}</version>
</dependency>
<!-- 依賴 客戶端 end -->2)配置網關地址以及秘鑰
圖片
3)編寫任務實現
@Service
publicclass DemoJob {
privatefinalstatic Logger logger = LoggerFactory.getLogger(DemoJob.class);
// 1、添加任務調度的自定義注解 RSAnnotation , 值是 job 的 bean值
// 2、ScheduleParam 調度參數
// 3、ScheduleResult 調度結果
@RSAnnotation(value = "myJobHandler")
public ScheduleResult doTestJob(ScheduleParam scheduleParam) {
logger.info("myJobHandler:" + JSON.toJSONString(scheduleParam));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
returnnew ScheduleResult(ScheduleResult.SUCCESS_CODE, "正常響應");
}
}4)啟動任務演示項目
圖片
展示了一個簡單的任務調度類 DemoJob,它包含一個可以被調度執行的方法 doTestJob ,該方法的注解是: myJobHandler , 與我們在 Admin 控制臺創建的測試任務保持一致。
啟動 DemoApplication ,本地執行結果:
圖片
如圖,每隔 15 秒,我們的控制臺會打印執行日志。
在 Admin 調度日志頁面,查看日志:
圖片
我們也發現啟動應用后,可以查看在線應用:
圖片
對于客戶端來講,任務執行是網關推送過來的,所以我們在家運行代碼也可以執行。網關會保存客戶端的出網 IP ,在線應用列表可以展示所有在線客戶端。





























