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. Nodejs.Electron(Nodejs的图形界面开发)安装和试用

    # 克隆示例项目的仓库 git clone https://github.com/electron/electron-quick-start # 进入这个仓库 cd electron-quick-st ...

  2. 排序1,2......n的无序数组,时间复杂度为o(n),空间复杂度为o(1)

    #include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _T ...

  3. 在MFC中通过访问IP地址下载文件到本地

    void CDownLoad::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 CDialogEx::OnOK(); UpdateData(TRUE); CStri ...

  4. 【CTF 攻略】CTF比赛中关于zip的总结

    [CTF 攻略]CTF比赛中关于zip的总结   分享到: --> 本文首发于安全客,建议到原地址阅读,地址:http://bobao.360.cn/ctf/detail/203.html 前言 ...

  5. MIP 脚本域名地址变更公告

    尊敬的 MIP 开发者: MIP 团队为了解决 MIP-Cache 页面下 cookie 相互覆盖问题,增强站点品牌露出,在 2017 年 8 月将 MIP 的脚本域名和 MIP-Cache 页面域名 ...

  6. k8s实践 - 如何优雅地给kong网关配置证书和插件。

    前言 从去年上半年微服务项目上线以来,一直使用kong作为微服务API网关,整个项目完全部署于k8s,一路走来,对于k8s,对于kong,经历了一个从无到有,从0到1的过程,也遇到过了一些坎坷,今天准 ...

  7. Word页眉、页码的使用:利用分隔符设置指定页显示页眉,解决页码显示{PAGE \* MERGEFORMAT}问题

    不常编辑对文档有格式要求的朋友来说,偶尔需要编辑指定格式页眉页码的word文档时,会一时不记得如何使用,在网上搜索半天,异常烦躁. 特整理一下,记录下来,备不时只需. 以下操作环境为word2016. ...

  8. [翻译 EF Core in Action 1.6]你的第一个EF Core应用程序

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  9. Java之mybatis详解

    文章大纲 一.mybatis介绍二.mybatis代码实战三.项目源码下载四.参考文章   一.mybatis介绍 1. mybatis是什么?   mybatis是一个持久层的框架,是apache下 ...

  10. [转]为什么复制构造函数的参数需要加const和引用

    [转]为什么复制构造函数的参数需要加const和引用 一.引言 1.0在解答这个问题之前,我们先跑个小程序,看下调用关系. #include <iostream> using namesp ...