我写了一个教学型的任务调度系统

1 架构概览

在我的职业生涯里,接触过如下 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 开源分布式协调框架,提供分布式同步、配置管理和服务发现,常用于分布式系统中。

项目仓库截图:

2 部署流程

勇哥将服务部署到 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 服务
bash 复制代码
 nohup java -Xms300m -Xmx350m -jar schedule-admin.jar  &
  • 启动 GateWay 服务
bash 复制代码
 nohup java -Xms200m -Xmx400m -jar schedule-gateway.jar  &
  • 启动 Worker 服务
bash 复制代码
 nohup java -Xms200m -Xmx300m -jar schedule-worker.jar  &

3 线上体验

01 登录

02 集群管理

因为 GateWay 、Woker 都需要向 Admin 注册实例信息,我们可以将 Admin 当做简单的注册中心,所以需要配置如下信息:

  • Admin 注册服务地址 ,格式是:ip1:10001;ip2:10001。
  • zk 集群地址 ,用于 Admin 集群,实现主从模式 。

03 添加应用

我们生产环境创建了1个应用,应用名是: mytest , appKey 为 1400001,客户端访问任务调度系统需要配置 appKey 和 appSecret 。

04 添加任务

我们定义了一个任务 ,名称是:测试任务,每 15 秒执行一次,jobHandler 定义为 myJobHandler 。

05 测试任务

从 gitcode 下载源码后 ,查看 Demo 模块 ,模块需要添加客户端依赖编写任务实现

1、客户端依赖

xml 复制代码
   <!--  依赖 客户端 start -->
  <dependency>
       <groupId>cn.javayong</groupId>
        <artifactId>schedule-client</artifactId>
        <version>${parent.version}</version>
  </dependency>
    <!--  依赖 客户端 end -->

2、配置网关地址以及秘钥

3、编写任务实现

java 复制代码
 @Service
 public class DemoJob {
 ​
     private final static 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) {
         }
         return new ScheduleResult(ScheduleResult.SUCCESS_CODE, "正常响应");
     }
     
 }

4、启动任务演示项目

展示了一个简单的任务调度类 DemoJob,它包含一个可以被调度执行的方法 doTestJob ,该方法的注解是: myJobHandler , 与我们在 Admin 控制台创建的测试任务保持一致。

启动 DemoApplication ,本地执行结果:

如图,每隔 15 秒,我们的控制台会打印执行日志。

在 Admin 调度日志页面,查看日志:

我们也发现启动应用后,可以查看在线应用:

对于客户端来讲,任务执行是网关推送过来的,所以我们在家运行代码也可以执行。网关会保存客户端的出网 IP ,在线应用列表可以展示所有在线客户端。

4 你可以学到什么

1、任务调度专栏

第一期已经开发完成,包含 JDK 常用调度类、Quartz 、Crontab 、ElasticJob、自研 platform-schedule 。

第二期会重点突出 XXL-JOB 的基本原理以及性能瓶颈,以及新一代任务调度系统 PowerJob 的原理(重点 讲解 DAG )。

2、网络编程

我基于 RocketMQ remoting 模块做了些许微调,Admin 服务、Gateway 服务、Worker 服务都是通过 TCP remoting 协议交互。

相比 RocketMQ 复杂的代码,platform-schedule 会简单很多,中高级工程师可以轻松掌握 Netty 编程知识,开阔眼界。

3、组件封装

platform-schedule 每个模块都有不同的组件,比如 worker 模块非常核心的调度组件是依赖 Quartz ,那么如何封装 Quartz 实现灵活的调度呢 ?

同时,Admin 为什么可以知道 Worker 、Gateway 的路由地址,因为它本身是一个简易的注册中心。

如何封装任务调度的 SDK ,并平滑的接入 Spring 生态。

相关推荐
运维@小兵8 小时前
SpringBoot获取用户信息常见问题(密码屏蔽、驼峰命名和下划线命名的自动转换)
java·spring boot·后端
问道飞鱼10 小时前
【springboot知识】配置方式实现SpringCloudGateway相关功能
java·spring boot·后端·gateway
樽酒ﻬق10 小时前
打造美观 API 文档:Spring Boot + Swagger 实战指南
java·spring boot·后端
ErizJ10 小时前
Golang | 位运算
开发语言·后端·golang·位运算
冼紫菜11 小时前
[特殊字符] Docker 从入门到实战:全流程教程 + 项目部署指南(含镜像加速)
运维·分布式·后端·docker·云原生·容器
秋野酱13 小时前
基于Spring Boot+Vue 网上书城管理系统设计与实现(源码+文档+部署讲解)
vue.js·spring boot·后端
编程毕设14 小时前
【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现
java·spring boot·后端
caihuayuan514 小时前
IOS 国际化词条 Python3 脚本
java·大数据·spring boot·后端·课程设计
我的golang之路果然有问题15 小时前
案例速成GO+Socket,个人笔记
开发语言·笔记·后端·websocket·学习·http·golang
boring_11116 小时前
全局id生成器生产方案
大数据·分布式·后端