Elastic-job基础入门实战

1.概述

Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。

Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供最轻量级的分布式任务的协调服务,外部依赖仅Zookeeper。

官网文档地址:http://elasticjob.io/

 

2.项目实战

第一步:引入maven依赖jar

<dependency>
    <groupId>com.dangdang</groupId>
    <artifactId>elastic-job-lite-core</artifactId>
    <version>2.1.5</version>
</dependency>
<dependency>
    <groupId>com.dangdang</groupId>
    <artifactId>elastic-job-lite-spring</artifactId>
    <version>2.1.5</version>
</dependency>
<dependency>
    <groupId>com.dangdang</groupId>
    <artifactId>elastic-job-common-core</artifactId>
    <version>2.1.5</version>
</dependency>

第二步:配置elasticjob.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="127.0.0.1:2181"
               namespace="dd-job"
               base-sleep-time-milliseconds="1000"
               max-sleep-time-milliseconds="3000"
               max-retries="3" />

<!-- 配置任务-->
<job:simple id="myElasticJob"
            class="com.task.MyElasticJob"
            registry-center-ref="regCenter"
            cron="*/10 * * * * ?"
            sharding-total-count="1"
            overwrite="true" >
    <!--监听器,定时任务执行前,执行后的处理-->
    <job:listener class="com.task.MyElasticJobListener"/>

    <!--分布式监听器,定时任务执行前,执行后的处理 只会在一台机器上面执行-->
    <job:distributed-listener class="com.task.MyAbstractDistributeOnceElasticJobListener"
                              started-timeout-milliseconds="30000"
                              completed-timeout-milliseconds="30000"/>
</job:simple>

    <!-- 配置带作业数据库事件追踪的简单作业-->
    <job:simple id="eventTraceElasticJob"
                class="com.task.MySimpleListenerElasticJob"
                registry-center-ref="regCenter"
                cron="*/10 * * * * ?"
                sharding-total-count="1"
                sharding-item-parameters="0=A,1=B,2=C"
                event-trace-rdb-data-source="dataSource">
    </job:simple>


</beans>

第三步:编写任务作业类,任务监听类

任务作业类  MyElasticJo.class

编写需要处理的业务逻辑

package com.task;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.UnknownHostException;


@Slf4j
public class MyElasticJob implements SimpleJob {

     @Override
     public void execute(ShardingContext shardingContext) {
          log.info("该执行定时任务了=========================");
          try {
               log.info("本机ip地址========================="+ InetAddress.getLocalHost().getHostAddress());
               log.info(String.format("------Thread ID: %s, 任务总片数: %s, 当前分片项: %s",
                                       Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem()));
               /**
                * 实际开发中,有了任务总片数和当前分片项,就可以对任务进行分片执行了
                * 比如 SELECT * FROM user WHERE status = 0 AND MOD(id, shardingTotalCount) = shardingItem
                */
          } catch (UnknownHostException e) {
               e.printStackTrace();
          }

     }
}

任务监听类  MyElasticJobListener.class   

任务作业前,作业后所需要处理的业务逻辑

package com.task;

import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyElasticJobListener implements ElasticJobListener {
    
    @Override
    public void beforeJobExecuted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======beforeJobExecuted");
    }
    
    @Override
    public void afterJobExecuted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======afterJobExecuted");
    }
}

任务监听类  MyAbstractDistributeOnceElasticJobListener.class

任务作业前,作业后所需要处理的业务逻辑-分布式应用中只会在一台服务器上面执行

package com.task;

import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.AbstractDistributeOnceElasticJobListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyAbstractDistributeOnceElasticJobListener extends AbstractDistributeOnceElasticJobListener {


    public MyAbstractDistributeOnceElasticJobListener(long startedTimeoutMilliseconds, long completedTimeoutMilliseconds) {
        super(startedTimeoutMilliseconds, completedTimeoutMilliseconds);
    }

    @Override
    public void doBeforeJobExecutedAtLastStarted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======doBeforeJobExecutedAtLastStarted");
    }

    @Override
    public void doAfterJobExecutedAtLastCompleted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======doAfterJobExecutedAtLastCompleted");
    }
}

任务作业类  MySimpleListenerElasticJob.class

编写需要处理的业务逻辑-带作业数据库事件追踪的简单作业(跟普通任务作业一样只是在配置中新增了event-trace-rdb-data-source="dataSource" 用于监控作业的状态)

package com.task;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.UnknownHostException;


@Slf4j
public class MySimpleListenerElasticJob implements SimpleJob {

     @Override
     public void execute(ShardingContext shardingContext) {
          log.info("Listener该执行定时任务了=========================");
          try {
               log.info("Listener本机ip地址========================="+ InetAddress.getLocalHost().getHostAddress());
               log.info(String.format("Listener------Thread ID: %s, 任务总片数: %s, 当前分片项: %s",
                                       Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem()));

              /**
                * 实际开发中,有了任务总片数和当前分片项,就可以对任务进行分片执行了
                * 比如 SELECT * FROM user WHERE status = 0 AND MOD(id, shardingTotalCount) = shardingItem
                */
          } catch (UnknownHostException e) {
               e.printStackTrace();
          }

     }
}

如上所述所有基础配置都已经配置完成,启动项目查看日志即可。具体详细配置根据自己业务配置,更多的配置参数请查看官网文档。

 

第二种方式:纯java代码方式

第一步:新增配置文件.yml文件也行 application.properties

reg-center.server-list: 127.0.0.1:2181
reg-center.namespace: elastic-job-lite-spring-boot

monitor.cron: 0/5 * * * * ?
monitor.sharding-total-count: 2
monitor.sharding-item-parameters: 0=CIB,1=ICBC
monitor.job-description: 监控
monitor.job-parameter: hello elastic job

第二步:新增作业,监听,配置java类

package com.config;

import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 作业配置
 */
@Configuration
public class MonitorJobConfig {

    @Autowired
    private ZookeeperRegistryCenter regCenter;

    @Autowired
    private ServiceMonitor serviceMonitor;

    @Autowired
    private LiteJobConfiguration liteJobConfiguration;

    @Autowired
    private ServiceListener serviceListener;

    @Bean(initMethod = "init")
    public JobScheduler simpleJobScheduler() {

        return new SpringJobScheduler(serviceMonitor
                , regCenter
                , liteJobConfiguration,serviceListener);
    }
}
package com.config;

import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 作业属性
 */
@Configuration
public class MonitorJobProperties {

    @Value("${monitor.cron:#{null}}")
    private String cron;

    @Value("${monitor.sharding-total-count:#{null}}")
    private int shardingTotalCount;

    @Value("${monitor.sharding-item-parameters:#{null}}")
    private String shardingItemParameters;

    @Value("${monitor.job-description:#{null}}")
    private String jobDescription;

    @Value("${monitor.job-parameter:#{null}}")
    private String jobParameter;

    @Autowired
    private ServiceMonitor serviceMonitor;

    @Bean
    public LiteJobConfiguration liteJobConfiguration() {
        JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder(serviceMonitor.getClass().getName()
                , cron, shardingTotalCount);
        JobCoreConfiguration jobCoreConfiguration = builder
                .shardingItemParameters(shardingItemParameters)
                .description(jobDescription)
                .jobParameter(jobParameter)
                .build();
        SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(jobCoreConfiguration, serviceMonitor.getClass().getCanonicalName());
        return LiteJobConfiguration
                .newBuilder(simpleJobConfiguration)
                .overwrite(true)
                .build();
    }


}
package com.config;

import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 注册中心配置
 */
@Configuration
public class RegistryCenterConfig {

    @Value("${reg-center.server-list:#{null}}")
    private String serverList;
    @Value("${reg-center.namespace:#{null}}")
    private String namespace;

    @Bean(initMethod = "init")
    public ZookeeperRegistryCenter regCenter() {
        return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
    }


}
package com.config;

import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ServiceListener implements ElasticJobListener {
    
    @Override
    public void beforeJobExecuted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======beforeJobExecuted");
    }
    
    @Override
    public void afterJobExecuted(ShardingContexts shardingContexts) {
        // do something ...
        log.info("该执行定时任务了======afterJobExecuted");
    }
}
package com.config;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 作业
 */
@Component
@Slf4j
public class ServiceMonitor implements SimpleJob {

    @Override
    public void execute(ShardingContext shardingContext) {
        log.info("sharding context is {}", shardingContext);
    }
}

所有基础配置已经完成,启动项目查看日志即可。

特别注意几点:

1、sharding-total-count:1 此配置值必须大于0,如果配置为0的话启动应用会报错,当你改为1或者大于1之后启动项目还是会报错,因为配置值注册到zookeeper中了,重启zookeeper也无效。必须找到zookeeper中的数据存储目录全部删除才行。(或者把 任务作业类配置的bean id 名称改掉也是可以的。)

2、项目中的zookeeper 版本需要与服务器上面的版本一致 。zookeeper版本也需要跟 curator-recipe 版本对应兼容,不然启动应用也会报错。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值