文章目录
- Elastic-Job 介绍
- 相关依赖
- elastic-job 目录结构
- SimpleJob 简单作业编码
- 下载并启动 ZooKeeper
- 编写定时任务代码并启动
Elastic-Job 介绍
概述:
Elastic-Job 是当当网开源的一个分布式调度解决方案,基于 Quartz 二次开发的,由两个相互独立的子项目 ElasticJob-Lite 和 Elastic-Job-Cloud 组成。ElasticJob-Lite 是一个轻量级无中心化的解决方案,它提供了分布式任务调度的核心功能,以 Jar 包的形式提供分布式任务的协调服务;而 Elastic-Job-Cloud 则是基于云环境下的分布式任务调度方案,需要结合 Mesos 和 Docker 使用,它采用了基于云原生的思想,以轻量级的微服务架构为基础,支持更大规模和复杂的分布式任务调度场景。
ElasticJob 是面向进程内的线程级调度框架。能够与 Spring 、Dubbo 等 Java 框架配合使用,在作业中可自由使用 Spring 注入的 Bean,如数据源连接池、Dubbo 远程服务等,更加方便的贴合业务开发。
弹性调度是 ElasticJob 最重要的功能,也是这款产品名称的由来。 它是一款能够让任务通过分片进行水平扩展的任务处理系统。
分片:
任务的分布式执行,需要将一个任务拆分为多个独立的任务项,然后由分布式的服务器分别执行某一个或几个分片项。
ElasticJob 中任务分片项的概念,使得任务可以在分布式的环境下运行,每台任务服务器只运行分配给该服务器的分片。随着服务器的增加或宕机,ElasticJob 会近乎实时的感知服务器数量的变更,从而重新为分布式的任务服务器分配更加合理的任务分片项,使得任务可以随着资源的增加而提升效率。
举例说明,如果作业分为 4 片,用两台服务器执行,则每个服务器分到 2 片,分别负责作业的 50% 的负载,如下图所示。
相关依赖
使用 ElasticJob 时,需要添加以下依赖包到项目中
引入 dangdang 依赖:
- 如果是简单 Java 项目,使用 elastic-job-lite-core 核心依赖:
<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <version>2.1.5</version> </dependency>
- 如果是集成到 Spring 框架中,使用 elastic-job-lite-spring 依赖,该依赖包含了 elastic-job-lite-core 核心依赖:
<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-spring</artifactId> <version>2.1.5</version> </dependency>
ElasticJob 已于 2020 年 5 月 28 日成为 Apache ShardingSphere 的子项目。当当更新到 2.1.5 版本,捐赠到 Apache 后,包名变更,从 3.0.0 版本开始更新:
- 如果是简单 Java 项目,使用 elasticjob-lite-core 核心依赖:(注意在加入 Apache 后 elastic-job 少了 “-” 变为 elasticjob)
<dependency> <groupId>org.apache.shardingsphere.elasticjob</groupId> <artifactId>elasticjob-lite-core</artifactId> <version>3.0.4</version> </dependency>
- 如果是集成到 Spring 框架中,使用 elasticjob-lite-spring-core 依赖,该依赖包含了 elasticjob-lite-core 核心依赖:
<dependency> <groupId>org.apache.shardingsphere.elasticjob</groupId> <artifactId>elasticjob-lite-spring-core</artifactId> <version>3.0.4</version> </dependency>
- 如果是集成到 Spring Boot 中,使用 elasticjob-lite-spring-boot-starter 启动器依赖,简化了在 Spring Boot 项目中使用 ElasticJob 的配置和依赖管理,提供了默认的配置和自动装配。
<dependency> <groupId>org.apache.shardingsphere.elasticjob</groupId> <artifactId>elasticjob-lite-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency>
elastic-job 目录结构
elastic-job
├──elastic-job-lite lite父模块,不应直接使用
├ ├──elastic-job-lite-core Java支持模块,可直接使用
├ ├──elastic-job-lite-spring Spring命名空间支持模块,可直接使用
├ ├──elastic-job-lite-lifecyle lite作业相关操作模块,不可直接使用
├ ├──elastic-job-lite-console lite界面模块,可直接使用
├──elastic-job-example 使用示例
├ ├──elastic-job-example-embed-zk 供示例使用的内嵌ZK模块
├ ├──elastic-job-example-jobs 作业示例
├ ├──elastic-job-example-lite-java 基于Java的使用示例
├ ├──elastic-job-example-lite-spring 基于Spring的使用示例
├ ├──elastic-job-example-lite-springboot 基于SpringBoot的使用示例
├──elastic-job-doc markdown生成文档的项目,使用方无需关注
├ ├──elastic-job-lite-doc lite相关文档
elastic-job-lite-core:
- 这是 ElasticJob-Lite 的核心模块,提供了 ElasticJob 的核心功能。
- 包含了分布式任务调度的基本功能,如任务的注册、启动、暂停、恢复、停止等。
- 支持多种作业类型,如简单作业(Simple Job)、数据流作业(Dataflow Job)和脚本作业(Script Job)等。
- 提供了分片策略、任务执行器等相关接口和实现。
elastic-job-lite-spring:
- 这是 ElasticJob-Lite 的 Spring 整合模块,用于与 Spring 框架集成。
- 提供了与 Spring 的无缝集成,可以通过 Spring 的配置文件或注解来定义和管理 ElasticJob 的作业。
- 支持通过 Spring 的方式配置和管理 ElasticJob 的作业信息、触发器、分片策略等。
elastic-job-lite-lifecycle:
- 这是 ElasticJob-Lite 的生命周期模块,用于管理作业的生命周期。
- 提供了在作业启动和关闭时执行一些额外的操作的扩展点。
- 可以通过实现相应的接口,在作业启动和关闭时执行自定义的逻辑,如初始化资源、清理资源等。
elastic-job-lite-console:
- 这是 ElasticJob-Lite 的控制台模块,用于提供可视化界面管理 ElasticJob。
- 可直接使用该模块来搭建一个 Web 界面,用于管理和监控 ElasticJob 的作业。
- 提供了作业配置、作业状态监控、作业运行日志等功能。
SimpleJob 简单作业编码
ElasticJob 调度器分为定时调度和一次性调度两种类型。 每种调度器启动时均需要注册中心配置、作业对象(或作业类型)以及作业配置这 3 个参数。
以下测试是在 windows 环境下进行。
下载并启动 ZooKeeper
这里下载 ZooKeeper 3.8.4 版本为例,需要下载的可以关注 【Qin的学习营地】公众号,回复【Zookeeper安装包】,包含安装包及源码。
1、解压安装包,找到解压目录下的 conf 目录,复制该目录下的 zoo_sample.cfg 文件,并重命名为 zoo.cfg。
2、根据需要修改 zoo.cfg 配置文件,比如将默认的数据存储路径 dataDir=/tmp/zookeeper 修改成自己的路径,还可以增加数据日志存储路径。
3、双击 bin 目录下的 zkServer.cmd,启动 Windows 环境下的 ZooKeeper 程序。
为什么需要做如上的配置操作,我们进入 bin 目录下,找到 zkEnv.cmd 并以文本形式打开,可以看到环境配置,启动 ZooKeeper 时会去找 conf 目录下的 zoo.cfg 配置文件。
编写定时任务代码并启动
这里集成到 Spring 框架中使用,并使用当当网下的依赖,所以引入 elastic-job-lite-spring 依赖。
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>2.1.5</version>
</dependency>
任务接口实现
实现 SimpleJob 接口,该接口仅提供单一方法,此方法将定时执行。重写该方法,编写自己的业务逻辑代码。
@Component
@Qualifier("myJob")
public class MyJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
switch (context.getShardingItem()) {
case 0:
System.out.println("执行分片0,dateTime:" + new Date(System.currentTimeMillis()));
break;
case 1:
System.out.println("执行分片1,dateTime:" + new Date(System.currentTimeMillis()));
break;
}
}
}
创建 Job 实例、注册配置及启动
1、注册中心配置
-
用于注册和协调作业分布式行为的组件,目前仅支持 ZooKeeper。
-
类名称:org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration
// zookeeper 服务器列表 "localhost:2181" // zookeeper 命名空间 "elastic-job-demo-zoo" CoordinatorRegistryCenter regCenter = new ZookeeperRegistryCenter(new ZookeeperConfiguration("localhost:2181" , "elastic-job-demo-zoo")); regCenter.init();
2、作业配置
-
ElasticJob 采用构建器模式创建作业配置对象。
-
类名称:org.apache.shardingsphere.elasticjob.api.JobConfiguration
// 定义作业核心配置 // 作业名称:"demoSimpleJob"、 CRON 表达式,控制作业触发时间:"0/15 * * * * ?"、 作业分片总数:2 JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder("demoSimpleJob", "0/15 * * * * ?", 2).build(); // 定义 SIMPLE 类型配置 SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(simpleCoreConfig, myJob.getClass().getCanonicalName()); // 定义 Lite 作业根配置 LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).build();
3、创建 Job 实例
-
创建 Job 实例
-
注册上述配置的注册中心、作业配置
-
启动运行实例
@Bean(initMethod = "init") public JobScheduler jobDemo() { System.out.println("jobDemo"); // 注册中心、job配置,JobScheduler init 方法启动 JobScheduler jobScheduler = new JobScheduler(createRegistryCenter(), createJobConfiguration()); return jobScheduler; } // @Bean // public void jobDemo1() { // System.out.println("执行 jobDemo1"); // new JobScheduler(createRegistryCenter(), createJobConfiguration()).init(); // }
完整代码:
@Configuration
public class JobConfig {
@Autowired
@Qualifier("myJob")
private SimpleJob myJob;
@Bean(initMethod = "init")
public JobScheduler jobDemo() {
System.out.println("jobDemo");
// 注册中心、job配置,JobScheduler init 方法启动
JobScheduler jobScheduler = new JobScheduler(createRegistryCenter(), createJobConfiguration());
return jobScheduler;
}
// @Bean
// public void jobDemo1() {
// System.out.println("执行 jobDemo1");
// new JobScheduler(createRegistryCenter(), createJobConfiguration()).init();
// }
private CoordinatorRegistryCenter createRegistryCenter() {
// zookeeper 服务器列表 "localhost:2181"
// zookeeper 命名空间 "elastic-job-demo-zoo"
CoordinatorRegistryCenter regCenter = new ZookeeperRegistryCenter(new ZookeeperConfiguration("localhost:2181"
, "elastic-job-demo-zoo"));
regCenter.init();
return regCenter;
}
private LiteJobConfiguration createJobConfiguration() {
// 定义作业核心配置
// 作业名称:"demoSimpleJob"、 CRON 表达式,控制作业触发时间:"0/15 * * * * ?"、 作业分片总数:2
JobCoreConfiguration simpleCoreConfig =
JobCoreConfiguration.newBuilder("demoSimpleJob", "0/15 * * * * ?", 2).build();
// 定义 SIMPLE 类型配置
SimpleJobConfiguration simpleJobConfig =
new SimpleJobConfiguration(simpleCoreConfig, myJob.getClass().getCanonicalName());
// 定义 Lite 作业根配置
LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).build();
return simpleJobRootConfig;
}
}
启动 spring boot 服务,运行结果:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
一个任务可以拆分为多个独立的分片项,分布式的服务器分别执行某一个或几个分片项。这里每隔 15s 执行一次任务。
详细官方文档资料,需要下载的可以关注 【Qin的学习营地】公众号,回复【elasticjob官方文档】。