Elastic-Job是当当⽹开源的⼀个分布式调度解决⽅案,基于Quartz⼆次开发的。
分布式调度:
在分布式环境中,任务能够按照指定条件执行。
例如:
1 项目部署在多台服务器上,其中定时任务只能有某一台主机执行,当此主机宕机其他定时任务选举其一执行。
2 分片执行、多台实例任务执行时,每个任务实例仅负责一部分的数据段任务。
如下图假设,每天0:05 执行统计一个日志表数据,分片1统计大于50岁的,分片2统计11-50岁的,分片3统计0-10岁的。这样每个定时任务分片负责一部分的内容。
一、 Elastic-Job-Lite 基础环境
jar依赖 + zookeeper
1. Jar依赖通过maven导入
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>2.1.5</version>
</dependency>
2. zookeeper启动
下载zookeeper启动程序:
在conf目录下 复制一份 zoo_sample.cfg 为 zoo.cfg
当前仅进行单实例启动 zookeeper,配置使用默认即可
# 每次心跳时间间隔 毫秒
tickTime=2000
# 初始化的心跳次数, 从Leader同步数据时,超出 心跳时间 x initLimit时则认为连不上
initLimit=10
# Leader通过心跳检测其他机器的连接状态、超出syncLimit x 心跳时间 则认为连不上
syncLimit=5
# znode存储路径、请自行设置,不要使用/tmp存储
dataDir=/Users/*****/project/zookeeper/zookeeper-3.4.9/data/
# 端口
clientPort=2181
启动:
bin/zkServer.sh start
停止:
bin/zkServer.sh stop
状态:
bin/zkServer.sh status
二、分布式定时任务实例
1. 选主执行的方式,只有一个实例执行 其他实例阻塞。
public class ElasticJobDemo {
public static void main(String[] args) {
// 1 配置协调任务的注册中心
// 配置zookeeper、第一个参数是主机地址集,第二个参数是调度时数据使用根位置节点。
// 通过zookeeper来协调调度,让任务按照指定规则进行执行。
ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration("localhost:2181", "timer-job");
// 协调任务的注册中心, 使用zookeeper 作为注册中心。
CoordinatorRegistryCenter registryCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
registryCenter.init(); // 进行初始化启动。
// 2 任务的策略执行配置。
String cron = "*/2 * * * * ?"; // 每2秒执行一次
int shardingTotalCount = 1; // 分片数
JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration.newBuilder("myJob", cron, shardingTotalCount).build();
// 3 创建任务用来实现具体业务(满足执行策略则会执行)
String jobClass = MyJobTimer.class.getName();
SimpleJobConfiguration job = new SimpleJobConfiguration(jobCoreConfiguration, jobClass);
// 4 启动任务
JobScheduler jobScheduler = new JobScheduler(registryCenter, LiteJobConfiguration.newBuilder(job).build());
jobScheduler.init();
}
// 自己创建的一个定时任务执行的实现
public static class MyJobTimer implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
System.out.println("我成功执行了 !!" );
}
}
}
2. 分片执行、每个实例负责一部分数据。
package org.ns.learn3.elastic;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobCoreConfiguration.Builder;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
public class ElasticJobDemo2 {
public static void main(String[] args) {
// 1 配置协调任务的注册中心
// 配置zookeeper、第一个参数是主机地址集,第二个参数是调度时数据使用根位置节点。
// 通过zookeeper来协调调度,让任务按照指定规则进行执行。
ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration("localhost:2181", "timer-job");
// 协调任务的注册中心, 使用zookeeper 作为注册中心。
CoordinatorRegistryCenter registryCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
registryCenter.init(); // 进行初始化启动。
// 2 任务的策略执行配置。
String cron = "*/2 * * * * ?"; // 每2秒执行一次
int shardingTotalCount = 3; // 分片数 (这里需要设置)
JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder("myJob-xx", cron, shardingTotalCount);
// 设置每个分片的参数 (这里需要设置)
builder.shardingItemParameters("0=param0,1=param1,2=param2");
JobCoreConfiguration jobCoreConfiguration = builder.build();
// 3 创建任务用来实现具体业务(满足执行策略则会执行)
String jobClass = MyJobTimer.class.getName();
SimpleJobConfiguration job = new SimpleJobConfiguration(jobCoreConfiguration, jobClass);
// 4 启动任务
JobScheduler jobScheduler = new JobScheduler(registryCenter, LiteJobConfiguration.newBuilder(job).build());
jobScheduler.init();
}
// 自己创建的一个定时任务执行的实现
public static class MyJobTimer implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
// 当前分片标识
int id = shardingContext.getShardingItem();
// 当前分片参数
String param = shardingContext.getShardingParameter();
// 通过参数可以确定数据操作的某个类型的数据,或者每个任务操作某一段的数据
System.out.println(String.format("我成功执行了 ,id:%d, param:%s", id, param) );
}
}
}