Elastic-Job,是一个基于Java编写的分布式调度框架,由当当网开源贡献出来。下图是该框架官网首页的介绍Elastic-Job介绍。
说到Java调度框架,Quartz应该是用得最多,但是一般都只是用Quartz做单机服务的调度服务。虽然Quartz也可以用作分布式调度,但往往需要自己手动实现,而Elastic-Job就是在整合Quartz和Zookeeper基础上,封装而成的一个分布式调度框架。
Elastic-Job有两种使用方式,分别是Elastic-Job-Lite和Elastic-Job-Cloud。其中Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务;Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能(如上图所示),官网对这两种使用方式有详细的说明。现在,用官方的一个简单的例子说明下Elastic-Job-Lite是如何使用的,代码做了部分删减,具体的代码可以从Elastic-Job码云地址和Elastic-Job github地址获取。
package com.dangdang.ddframe.job.example.job.simple;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import java.text.SimpleDateFormat;
import java.util.Date;
public class JavaSimpleJob implements SimpleJob {
@Override
public void execute(final ShardingContext shardingContext) {
System.out.println(String.format("Item: %s | Time: %s | Thread: %s | %s",
shardingContext.getShardingItem(),
new SimpleDateFormat("HH:mm:ss").format(new Date()),
Thread.currentThread().getId(), "SIMPLE"));
}
}
代码说明如下:
(1)public class JavaSimpleJob implements SimpleJob
Elastic-Job-Lite任务需要实现SimpleJob这个接口
(2)public void execute(final ShardingContext shardingContext)
需要在execute方法中定义自己的业务逻辑,其中,ShardingContext 是分片上下文
以上便定义了一个简单的Elastic-Job-Lite任务。下面介绍生成控制器进行该任务的调度
package com.dangdang.ddframe.job.example;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.config.script.ScriptJobConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import com.dangdang.ddframe.job.example.job.dataflow.JavaDataflowJob;
import com.dangdang.ddframe.job.example.job.simple.JavaSimpleJob;
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;
import org.apache.commons.dbcp.BasicDataSource;
import javax.sql.DataSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermissions;
public final class JavaMain {
private static final int EMBED_ZOOKEEPER_PORT = 4181;
private static final String ZOOKEEPER_CONNECTION_STRING = "localhost:" + EMBED_ZOOKEEPER_PORT;
private static final String JOB_NAMESPACE = "elastic-job-example-lite-java";
// switch to MySQL by yourself// private static final String EVENT_RDB_STORAGE_DRIVER = "com.mysql.jdbc.Driver";// private static final String EVENT_RDB_STORAGE_URL = "jdbc:mysql://localhost:3306/elastic_job_log";
private static final String EVENT_RDB_STORAGE_DRIVER = "org.h2.Driver";
private static final String EVENT_RDB_STORAGE_URL = "jdbc:h2:mem:job_event_storage";
private static final String EVENT_RDB_STORAGE_USERNAME = "sa";
private static final String EVENT_RDB_STORAGE_PASSWORD = "";
// CHECKSTYLE:OFF public static void main(final String[] args) throws IOException {
// CHECKSTYLE:ON EmbedZookeeperServer.start(EMBED_ZOOKEEPER_PORT);
CoordinatorRegistryCenter regCenter = setUpRegistryCenter();
JobEventConfiguration jobEventConfig = new JobEventRdbConfiguration(setUpEventTraceDataSource());
JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder("javaSimpleJob", "0/5 * * * * ?", 3).shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").build();
SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, JavaSimpleJob.class.getCanonicalName());
new JobScheduler(regCenter, LiteJobConfiguration.newBuilder(simpleJobConfig).build(), jobEventConfig).init();
}
控制器代码说明如下:
(1)EmbedZookeeperServer.start(EMBED_ZOOKEEPER_PORT);
启动内嵌的zookeeper。因为Elastic-Job需要依赖一个注册中心,默认使用zookeeper,所以在启动Elastic-Job任务前需要先连接zookeeper。
(2)CoordinatorRegistryCenter regCenter = setUpRegistryCenter();
CoordinatorRegistryCenter 用作分布式调度的注册中心,用zookeeper实现
(3)JobEventConfiguration jobEventConfig = new JobEventRdbConfiguration(setUpEventTraceDataSource());
JobEventConfiguration 是作业事件配置标识接口。这里将作业事件存入关系型数据库中,数据中用h2,当然也可以存入mysql中。
(4)JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder("javaSimpleJob", "0/5 * * * * ?", 3).shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").build();
JobCoreConfiguration 是作业的核心配置。javaSimpleJob表示作业的名称,0/5 * * * *设置作业调度的间隔,3表示作业的分片。shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou")表示设置分片的序列号和个性化参数。
(5)SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, JavaSimpleJob.class.getCanonicalName());
SimpleJobConfiguration 表示Lite作业的简单配置。
(6) new JobScheduler(regCenter, LiteJobConfiguration.newBuilder(simpleJobConfig).build(), jobEventConfig).init();
生成JobScheduler对象并初始化执行。
最终程序输入如下所示:控制台任务输出,Item表示分片