Elastic-Job是当当网的任务调度开源框架,有以下功能

分布式调度协调
弹性扩容缩容
失效转移
错过执行作业重触发
作业分片一致性,保证同一分片在分布式环境中仅一个执行实例
自诊断并修复分布式不稳定造成的问题
支持并行调度
支持作业生命周期操作
丰富的作业类型
Spring整合以及命名空间提供
运维平台

具体信息可以查看 官网,Elastic-Job的文档很详细,同时也有相应的demo。但是,美中不足的是他的springboot版本的demo用的是xml结构的。网上的例子都有点乱,花了点时间整合了下,现在就开始吧。

快速入门


1.pom文件

        <elastic-job.version>2.1.5</elastic-job.version>

<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>${elastic-job.version}</version>
</dependency>
<!-- elastic-job-lite-spring -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>${elastic-job.version}</version>
</dependency>

2.定义zookeeper

@Configuration
public class ElasticRegCenterConfig {
/**
* 配置zookeeper
* @param serverList
* @param namespace
* @return
*/
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter(
@Value("${regCenter.serverList}") final String serverList,
@Value("${regCenter.namespace}") final String namespace) {
return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
}
}

3.定义job

@Component
public class SimpleJobDemo implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
System.out.println(String.format("------Thread ID: %s, 任務總片數: %s, " +
"当前分片項: %s.当前參數: %s," +
"当前任務名稱: %s.当前任務參數: %s"
,
Thread.currentThread().getId(),
shardingContext.getShardingTotalCount(),
shardingContext.getShardingItem(),
shardingContext.getShardingParameter(),
shardingContext.getJobName(),
shardingContext.getJobParameter() ));
}
}

4.定义任务监听器,统计每次任务执行的时间

public class MyElasticJobListener implements ElasticJobListener {
private static final Logger logger = LoggerFactory.getLogger(MyElasticJobListener.class); private long beginTime = 0;
@Override
public void beforeJobExecuted(ShardingContexts shardingContexts) {
beginTime = System.currentTimeMillis(); logger.info("===>{} JOB BEGIN TIME: {} <===",shardingContexts.getJobName(), TimeUtil.mill2Time(beginTime));
} @Override
public void afterJobExecuted(ShardingContexts shardingContexts) {
long endTime = System.currentTimeMillis();
logger.info("===>{} JOB END TIME: {},TOTAL CAST: {} <===",shardingContexts.getJobName(), TimeUtil.mill2Time(endTime), endTime - beginTime);
}
}

5.配置JobConfiuration,配置job随容器一起启动

@Configuration
public class ElasticJobConfig {
@Autowired
private ZookeeperRegistryCenter regCenter;
/**
* 配置任务监听器
* @return
*/
@Bean
public ElasticJobListener elasticJobListener() {
return new MyElasticJobListener();
}
/**
* 配置任务详细信息
* @param jobClass
* @param cron
* @param shardingTotalCount
* @param shardingItemParameters
* @return
*/
private LiteJobConfiguration getLiteJobConfiguration(final Class<? extends SimpleJob> jobClass,
final String cron,
final int shardingTotalCount,
final String shardingItemParameters) {
return LiteJobConfiguration.newBuilder(new SimpleJobConfiguration(
JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount)
.shardingItemParameters(shardingItemParameters).build()
, jobClass.getCanonicalName())
).overwrite(true).build();
}
@Bean(initMethod = "init")
public JobScheduler simpleJobScheduler(final SimpleJobDemo simpleJob,
@Value("${stockJob.cron}") final String cron,
@Value("${stockJob.shardingTotalCount}") final int shardingTotalCount,
@Value("${stockJob.shardingItemParameters}") final String shardingItemParameters) {
MyElasticJobListener elasticJobListener = new MyElasticJobListener();
return new SpringJobScheduler(simpleJob, regCenter,
getLiteJobConfiguration(simpleJob.getClass(), cron, shardingTotalCount, shardingItemParameters),
elasticJobListener);
}
}

配置文件如下

server.port=${random.int[10000,19999]}
regCenter.serverList = localhoost:2181
regCenter.namespace = elastic-job-lite-springboot stockJob.cron = 0/5 * * * * ?
stockJob.shardingTotalCount = 4
stockJob.shardingItemParameters = 0=0,1=1,2=0,3=1

启动项目,输出

大家可以仔细的观察下配置文件和输出的对应关系。假设我先有这样的需求。

定时任务在两台主机上A,B同时运行.A处理id是奇数的数据,B处理Id为偶数的数据

用传统的定时任务例如@Schedule注解能实现么?那当然是可以,直接写死硬编码即可。用Elastic-Job的话,则相当灵活,示例如下

public class DbQueryJob implements SimpleJob {
@Autowired
private XXXDao xxxDao;
@Override
public void execute(ShardingContext shardingContext) {
String shardingParameter = shardingContext.getShardingParameter();
//mod是对id取余后的结果
List<xxx> xxxlists=xxxDao.select("select * from table where mod="+shardingParameter);
xxxlists.forEach(x->{
System.out.println("参数:"+shardingContext.getShardingParameter()+"状态"+x.getStatus());
});
}
}

稍微讲下原理

Elastic-Job默认采用平均分片策略

如果有3台服务器,分成9片,则每台服务器分到的分片是:1=[0,1,2], 2=[3,4,5], 3=[6,7,8]

如果有3台服务器,分成8片,则每台服务器分到的分片是:1=[0,1,6], 2=[2,3,7], 3=[4,5]

如果有3台服务器,分成10片,则每台服务器分到的分片是:1=[0,1,2,9], 2=[3,4,5], 3=[6,7,8]

上述配置文件我们分成4片,A服务分到0,1  B服务分到2,3,同时 shardingItemParameters 参数表明了每个分片对应的ItemParameters,所以A服务的 shardingContext.getShardingParameter()=0

通过这样的逻辑,我们就能实现我们的分片业务了。

以上,就是Springboot整合Elastic-Job

源码

Springboot整合Elastic-Job的更多相关文章

  1. SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践

    一. 前言 日志对于一个程序的重要程度不用过多的言语修饰,本篇将以实战的方式讲述开源微服务全栈项目 有来商城 是如何整合当下主流日志解决方案 ELK +Filebeat . 话不多说,先看实现的效果图 ...

  2. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  3. springboot整合elasticsearch(基于es7.2和官方high level client)

    前言 最近写的一个个人项目(传送门:全终端云书签)中需要用到全文检索功能,目前 mysql,es 都可以做全文检索,mysql 胜在配置方便很快就能搞定上线(参考这里),不考虑上手难度,es 在全文检 ...

  4. SpringBoot整合ES+Kibana

    前言:最近在写一个HTTP代理服务器,记录日志使用的是ES,所以涉及到SpringBoot和ES的整合,整合完毕后又涉及到数据可视化分析,所以使用了Kibana进行管理,有些坑,需要记录一下 Spri ...

  5. spring-boot整合mybatis(1)

    sprig-boot是一个微服务架构,加快了spring工程快速开发,以及简便了配置.接下来开始spring-boot与mybatis的整合. 1.创建一个maven工程命名为spring-boot- ...

  6. SpringBoot整合Mybatis之项目结构、数据源

    已经有好些日子没有总结了,不是变懒了,而是我一直在奋力学习springboot的路上,现在也算是完成了第一阶段的学习,今天给各位总结总结. 之前在网上找过不少关于springboot的教程,都是一些比 ...

  7. springboot整合mq接收消息队列

    继上篇springboot整合mq发送消息队列 本篇主要在上篇基础上进行activiemq消息队列的接收springboot整合mq发送消息队列 第一步:新建marven项目,配置pom文件 < ...

  8. springboot整合mybaits注解开发

    springboot整合mybaits注解开发时,返回json或者map对象时,如果一个字段的value为空,需要更改springboot的配置文件 mybatis: configuration: c ...

  9. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  10. SpringBoot整合Kafka和Storm

    前言 本篇文章主要介绍的是SpringBoot整合kafka和storm以及在这过程遇到的一些问题和解决方案. kafka和storm的相关知识 如果你对kafka和storm熟悉的话,这一段可以直接 ...

随机推荐

  1. 多线程动态规划算法求解TSP(Traveling Salesman Problem) 并附C语言实现例程

    TSP问题描述: 旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人要拜访n个城市,他必须 ...

  2. 时间戳转换成时间js(年-月-日,例如“2017-04-22”)

    function GetDateByShiJianChuo(timespan) { var date = new Date(parseInt(timespan.replace("/Date( ...

  3. mysql保存不了4字节的问题(也就是表情)

    这个问题   https://blog.csdn.net/ppwangGS/article/details/62044887 有详细的解决办法 这里我就是记录一下我遇到的问题 这种问题一般是往数据库 ...

  4. MIP ACCESS细节剖析

    什么是 MIP ACCESS MIP ACCESS 由百度 MIP 团队开发的一种页面访问权限控制机制,能够允许网页发布者在页面元素中定义内容标记,并结合用户访问情况进行综合评价,从而展现或隐藏页面中 ...

  5. 小程序 textarea、input 层级过高,导致填写内容穿透,z-index无效问题解决方案。

    小程序的textare.input输入框层级是最高的 那么我们在textare.input输入的内容就会总是显示在最上一层. 这是时为什么呢?官方文档有说明,因为textare.input这些是原生组 ...

  6. Spark学习之键值对操作总结

    键值对 RDD 是 Spark 中许多操作所需要的常见数据类型.键值对 RDD 通常用来进行聚合计算.我们一般要先通过一些初始 ETL(抽取.转化.装载)操作来将数据转化为键值对形式.键值对 RDD ...

  7. 从壹开始 [ Nuxt.js ] 之二 || 项目搭建 与 接口API

    前言 哈喽大家周一好,今天的内容比较多,主要就是包括:把前端页面的展示页给搭出来,然后调通接口API,可以添加数据,这两天我也一直在开发,本来想一篇一篇的写,发现可能会比较简单,就索性把项目搭建的过程 ...

  8. 由ORACLE:ORA-28001: the password has expired(密码过期)引起ODI资料库连接失败

    今天,连接ODI,出现下面的错误 oracle.odi.core.config.WorkRepositoryResourceFailureException: ODI-10182: 资料档案库访问期间 ...

  9. 【重学计算机】操作系统D6章:并发程序设计

    1. 并发程序的基本概念 程序顺序性 内部顺序性:CPU严格按照顺序执行指令 外部顺序性:程序员设计程序时往往用顺序设计的思想 顺序程序特性 程序执行的顺序性 计算环境的封闭性: 程序执行时犹如独占资 ...

  10. 【Android Studio安装部署系列】目录

    概述 从刚开始使用Android Studio到现在,下面所有目录下的操作,当时习惯性的把每一个整理成一个文档(其实就是简单文字描述+截图):有些地方当时是一知半解,现在会稍微明白一些.正好赶上现在有 ...