Elastic-job实战(分布式作业调度框架)

就拿一个场景来说吧,如果我们的项目是部署到多台机器上,那么某一时刻,我们的定时任务肯定每台机器上都会执行一遍,那这肯定不是我们想要的结果,我们只希望有一台机器能执行。

一.前言

Elastic job是当当网架构师基于Zookepper、Quartz开发并开源的一个Java分布式定时任务。Elastic job主要的功能有支持弹性扩容,通过Zookepper集中管理和监控job,支持失效转移等,这些都是Quartz等其他定时任务无法比拟的。

官网说明:

目前Elastic job的最新版本已经由原来的elastic-job-core分离除了两个项目,分别为Elastic-Job-LiteElastic-Job-Cloud。Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。
Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。
Elastic-Job-Cloud使用Mesos +Docker(TBD)的解决方案,额外提供资源治理、应用分发以及进程隔离等服务,Elastic-Job-Lite和Elastic-Job-Cloud提供同一套API开发作业,开发者仅需一次开发,即可根据需要以Lite或Cloud的方式部署。

github: https://github.com/dangdangdotcom/elastic-job


二.如何使用Elastic-Job

Elastic-job提供3种类型作业:

1.Simple类型作业
2.Dataflow类型作业
3.Script类型作业

这里我们用第一种测试。


2.1 添加依赖

  <dependency>
      <groupId>com.dangdanggroupId>
      <artifactId>elastic-job-springartifactId>
      <version>1.1.1version>
 dependency>

2.2 添加配置文件application.properties

################################## Elastic-Job ##################################
regCenter.namespace=my-job
regCenter.zk.address=localhost1:2181,localhost2:2181
regCenter.baseSleepTimeMilliseconds=1000
regCenter.maxSleepTimeMilliseconds=3000
regCenter.maxRetries=3
regCenter.sessionTimeoutMilliseconds=10000
#如果为true,可以在控制台检测到作业的执行状态
job.monitorExecution=true
#失效转移,如果为true,当作业在执行过程中异常中断,作业会被分发到集群中存活的结点
job.failover=true
#如果为true,在开始部署的时候作业不会自启动,即使到了触发时间,需要在控制台手动触发。
job.disabled=false
#如果为true,则会覆盖zk的配置
job.overwrite=true
job.monitorPort=9888
#只有当分片的数量设置为1的时候,整个集群中只会有一个进程去执行该Job,在服务器数量没有波动的情况下,任务总会在固定某个进程上执行。在作业执行前进程如果挂了,那作业会被分配到集群某一个存活的进程中
job.shardingTotalCount=1
job.shardingItemParameters=

2.3 配置zk和Job application-Context-jobs.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:reg="http://www.dangdang.com/schema/ddframe/reg"
       xmlns:job="http://www.dangdang.com/schema/ddframe/job"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.dangdang.com/schema/ddframe/reg
                        http://www.dangdang.com/schema/ddframe/reg/reg.xsd
                        http://www.dangdang.com/schema/ddframe/job
                        http://www.dangdang.com/schema/ddframe/job/job.xsd">
    <reg:zookeeper id="regCenter"
                   server-lists="${regCenter.zk.address}"
                   namespace="${regCenter.namespace}-${env}"
                   base-sleep-time-milliseconds="${regCenter.baseSleepTimeMilliseconds}"
                   max-sleep-time-milliseconds="${regCenter.maxSleepTimeMilliseconds}"
                   max-retries="${regCenter.maxRetries}"
                   nested-port="-1"
                   session-timeout-milliseconds="${regCenter.sessionTimeoutMilliseconds}"/>

    <job:simple id="myJob"
                class="com.xx.job.MyJob"
                registry-center-ref="regCenter"
                sharding-total-count="${job.shardingTotalCount}"
                cron="0/5 * * * * ?"
                sharding-item-parameters="${job.shardingItemParameters}"
                monitor-execution="${job.monitorExecution}"
                monitor-port="${job.monitorPort}"
                failover="${job.failover}"
                description="我的job"
                disabled="${job.disabled}"
                overwrite="${job.overwrite}"/>
beans>

2.4 封装执行器(并行和串行)

串行任务执行器

/**
 * 串行任务执行器
 */
public abstract class AbstractSerialExecutor extends AbstractSimpleElasticJob {
    public abstract void executeJob(String jobName);

    @Override
    public void process(JobExecutionMultipleShardingContext shardingContext) {
        long t1 = System.currentTimeMillis();
        executeJob(shardingContext.getJobName());
        LogUtil.successJob(shardingContext.getJobName(), (System.currentTimeMillis() - t1));
    }
}

并行任务执行器

/**
 * 并行任务执行器
 */
public abstract class AbstractParallelExecutor extends AbstractSimpleElasticJob implements Runnable {
    @Override
    public void process(JobExecutionMultipleShardingContext shardingContext) {
        something....
    }
}

2.5 编写Job

@Component
public class MyJob extends AbstractSerialExecutor {
    private final static Logger logger = LoggerFactory.getLogger(MyJob.class);
    @Override
    public void executeJob(String jobName) {
        System.out.println("*****************Myjob.....");
    }
}

3.Elastic-Job监控后台搭建

Elastic-job实战(分布式作业调度框架)_第1张图片
下载地址:https://github.com/elasticjob/elastic-job-lite/tree/dev/elastic-job-lite-console

具体怎么弄,可以去搜一个教程…

Elastic-job实战(分布式作业调度框架)_第2张图片

zookeeper里面保存了我们Job的信息:

Elastic-job实战(分布式作业调度框架)_第3张图片



4.测试分布式定时任务

我们把我们项目打成jar包,本地启动一个,另一台服务器也启动。我们发现只有一台服务器在运行定时任务:( 0/5 * * * * ?)每5秒跑一次…

Elastic-job实战(分布式作业调度框架)_第4张图片

Elastic-job实战(分布式作业调度框架)_第5张图片

这里我们做一个实验,我们假设一台服务器宕机了(现在在跑定时任务的主机),会怎么样?

Elastic-job实战(分布式作业调度框架)_第6张图片

Elastic-job实战(分布式作业调度框架)_第7张图片

使用Elastic-job轻松帮我们实现分布式定时任务,原理应该都一样。我推测:zookeeper的Leader选举,哪台机器被选为Leader,那他就跑任务。


扩展

Elastic-Job监控平台也给我们提供了便利,我们可以轻松监控作业,配置作业…
Elastic-job实战(分布式作业调度框架)_第8张图片

Elastic-job实战(分布式作业调度框架)_第9张图片

Elastic-job实战(分布式作业调度框架)_第10张图片

你可能感兴趣的:(工作实习)