elastic-job的原理简介和使用
转载:http://blog.csdn.net/fanfan_v5/article/details/61310045
elastic-job是当当开源的一款非常好用的作业框架,在这之前,我们开发定时任务一般都是使用quartz或者spring-task(ScheduledExecutorService),无论是使用quartz还是spring-task,我们都会至少遇到两个痛点:
1.不敢轻易跟着应用服务多节点部署,可能会重复多次执行而引发系统逻辑的错误。
2.quartz的集群仅仅只是用来HA,节点数量的增加并不能给我们的每次执行效率带来提升,即不能实现水平扩展。
本篇博文将会自顶向下地介绍elastic-job,让大家认识了解并且快速搭建起环境。
elastic-job产品线说明
elastic-job在2.x之后,出了两个产品线:Elastic-Job-Lite和Elastic-Job-Cloud。我们一般使用Elastic-Job-Lite就能够满足需求,本文也是以Elastic-Job-Lite为主。1.x系列对应的就只有Elastic-Job-Lite,并且在2.x里修改了一些核心类名,差别虽大,原理类似,建议使用2.x系列。写此博文,最新release版本为2.0.5。
elastic-job-lite原理
elastic-job就可以帮助我们解决上面的问题,elastic底层的任务调度还是使用的quartz,通过zookeeper来动态给job节点分片。
我们来看:
很大体量的用户需要在特定的时间段内计息完成
我们肯定是希望我们的任务可以通过集群达到水平扩展,集群里的每个节点都处理部分用户,不管用户数量有多庞大,我们只要增加机器就可以了,比如单台机器特定时间能处理n个用户,2台机器处理2n个用户,3台3n,4台4n...,再多的用户也不怕了。
使用elastic-job开发的作业都是zookeeper的客户端,比如我希望3台机器跑job,我们将任务分成3片,框架通过zk的协调,最终会让3台机器分别分配到0,1,2的任务片,比如server0-->0,server1-->1,server2-->2,当server0执行时,可以只查询id%3==0的用户,server1执行时,只查询id%3==1的用户,server2执行时,只查询id%3==2的用户。
任务部署多节点引发重复执行
在上面的基础上,我们再增加server3,此时,server3分不到任务分片,因为只有3片,已经分完了。没有分到任务分片的作业程序将不执行。
如果此时server2挂了,那么server2的分片项会分配给server3,server3有了分片,就会替代server2执行。
如果此时server3也挂了,只剩下server0和server1了,框架也会自动把server3的分片随机分配给server0或者server1,可能会这样,server0-->0,server1-->1,2。
这种特性称之为弹性扩容,即elastic-job名称的由来。
代码演示
本地宿主机器
zookeeper、job
192.168.241.1
虚拟机
job
192.168.241.128
环境说明:
Java
请使用JDK1.7及其以上版本。
Zookeeper
请使用Zookeeper3.4.6及其以上版本
Elastic-Job-Lite
2.0.5(2.x系列即可,最好是2.0.4及其以上,因为2.0.4版本有本人提交的少许代码,(*^__^*) 嘻嘻……)
需求说明:
通过两台机器演示动态分片
- <!-- 引入elastic-job-lite核心模块 -->
- <dependency>
- <groupId>com.dangdang</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>2.0.5</version>
- </dependency>
- <!-- 使用springframework自定义命名空间时引入 -->
- <dependency>
- <groupId>com.dangdang</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
- <version>2.0.5</version>
- </dependency>
- package com.fanfan.sample001;
- import com.dangdang.ddframe.job.api.ShardingContext;
- import com.dangdang.ddframe.job.api.simple.SimpleJob;
- import java.util.Date;
- /**
- * Created by fanfan on 2016/12/20.
- */
- public class MySimpleJob implements SimpleJob {
- @Override
- public void execute(ShardingContext shardingContext) {
- System.out.println(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
- */
- }
- }
Step3. Spring配置
- <?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="192.168.241.1:2181" namespace="dd-job"
- base-sleep-time-milliseconds="1000" max-sleep-time-milliseconds="3000" max-retries="3" />
- <!-- 配置作业-->
- <job:simple id="mySimpleJob" class="com.fanfan.sample001.MySimpleJob" registry-center-ref="regCenter"
- sharding-total-count="2" cron="0/2 * * * * ?" overwrite="true" />
- </beans>
Case1. 单节点
作业类型
SimpleJob需要实现SimpleJob接口,意为简单实现,未经过任何封装,与quartz原生接口相似,比如示例代码中所使用的job。
Dataflow类型用于处理数据流,需实现DataflowJob接口。该接口提供2个方法可供覆盖,分别用于抓取(fetchData)和处理(processData)数据。
可通过DataflowJobConfiguration配置是否流式处理。
流式处理数据只有fetchData方法的返回值为null或集合长度为空时,作业才停止抓取,否则作业将一直运行下去; 非流式处理数据则只会在每次作业执行过程中执行一次fetchData方法和processData方法,随即完成本次作业。
实际开发中,Dataflow类型的job还是很有好用的。
- package com.fanfan.sample001;
- import com.dangdang.ddframe.job.api.ShardingContext;
- import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Created by fanfan on 2016/12/23.
- */
- public class MyDataFlowJob implements DataflowJob<User> {
- /*
- status
- 0:待处理
- 1:已处理
- */
- @Override
- public List<User> fetchData(ShardingContext shardingContext) {
- List<User> users = null;
- /**
- * users = SELECT * FROM user WHERE status = 0 AND MOD(id, shardingTotalCount) = shardingItem Limit 0, 30
- */
- return users;
- }
- @Override
- public void processData(ShardingContext shardingContext, List<User> data) {
- for (User user: data) {
- System.out.println(String.format("用户 %s 开始计息", user.getUserId()));
- user.setStatus(1);
- /**
- * update user
- */
- }
- }
- }
- <job:dataflow id="myDataFlowJob" class="com.fanfan.sample001.MyDataFlowJob" registry-center-ref="regCenter"
- sharding-total-count="2" cron="0 0 02 * * ?" streaming-process="true" overwrite="true" />
其它功能
这些增强的功能读者可以在github/elastic-job上自行学习,相信有了本篇博文的基础,再阅读那些文档就特别简单了。
elastic-job的原理简介和使用的更多相关文章
- storm 原理简介及单机版安装指南——详细版【转】
storm 原理简介及单机版安装指南 本文翻译自: https://github.com/nathanmarz/storm/wiki/Tutorial 原文链接自:http://www.open-op ...
- Java进阶(二十四)Java List集合add与set方法原理简介
Java List集合add与set方法原理简介 add方法 add方法用于向集合列表中添加对象. 语法1 用于在列表的尾部插入指定元素.如果List集合对象由于调用add方法而发生更改,则返回 tr ...
- kafka原理简介并且与RabbitMQ的选择
kafka原理简介并且与RabbitMQ的选择 kafka原理简介,rabbitMQ介绍,大致说一下区别 Kafka是由LinkedIn开发的一个分布式的消息系统,使用Scala编写,它以可水平扩展和 ...
- InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)
上一篇文章中对ThreadLocal进行了详尽的介绍,另外还有一个类: InheritableThreadLocal 他是ThreadLocal的子类,那么这个类又有什么作用呢? 测试代码 p ...
- Nginx 负载均衡原理简介与负载均衡配置详解
Nginx负载均衡原理简介与负载均衡配置详解 by:授客 QQ:1033553122 测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制 ...
- Nginx 反向代理工作原理简介与配置详解
Nginx反向代理工作原理简介与配置详解 by:授客 QQ:1033553122 测试环境 CentOS 6.5-x86_64 nginx-1.10.0 下载地址:http://nginx. ...
- Linux DNS原理简介及配置
Linux DNS原理简介及配置 DNS简介 DNS原理 域名解析的过程 资源记录 DNS BIND安装配置 一.简介 一般来讲域名比IP地址更加的有含义.也更容易记住,所以通常用户更习惯输入域名来访 ...
- Oracle Golden Gate原理简介
Oracle Golden Gate原理简介 http://www.askoracle.org/oracle/HighAvailability/20140109953.html#6545406-tsi ...
- Linux SSH基于密钥交换的自动登陆原理简介及配置说明
一.原理简介 SSH证书认证登录的基础是一对唯一匹配密钥: 私钥(private key)和公钥(public key).公钥用于对数据进行加密,而且只能用于加密.而私钥只能对使用所匹配的公钥,所加密 ...
- Socket通信原理简介
Socket通信原理简介 字数1011 阅读1766 评论2 喜欢11 何谓socket 计算机,顾名思义即是用来做计算.因而也需要输入和输出,输入需要计算的条件,输出计算结果.这些输入输出可以抽象为 ...
随机推荐
- 如何用新安装的jdk替换掉Linux系统默认jdk
版主写的非常棒: http://blog.csdn.net/u011364306/article/details/48375653
- 编程中的链式调用:Scala示例
编程中的链式调用与Linux Shell 中的管道类似.Linux Shell 中的管道 ,会将管道连接的上一个程序的结果, 传递给管道连接的下一个程序作为参数进行处理,依次串联起N个实用程序形成流水 ...
- Hive使用pmod函数实现dayofweek函数功能
dayofweek在hive2.2.0开始支持,低版本的hive原生未提供dayofweek函数(获取一个日期是星期几的方法),所以只有我们自己编写udf函数提供,udf就不说了,在这里给出了一个使用 ...
- oracle表分区、表分析及oracle数据泵文件导入导出
1.先说oracle表分区是什么吧 你有500万份文件,你要把他存在磁盘上,好嘛,我们就一个文件夹,500万分文件在那儿杵着,我们想找到要的那个打开,嘿嘿,我们得找到什么时候. 这时候,有个人告诉你, ...
- 5、CentOS 6.5系统安装配置Nginx-1.2.7+PHP-5.3.22环境
一,操作系统 以最小服务器形式安装系统,并添加开发工具库,便于后期编译使用. 此处基本都是下一步,下一步,不再废话. 安装完成,进入系统,调通网络,关闭防火墙或打开相应的WEB端口. 以下安装操作默认 ...
- 前端框架VUE----webpack打包工具的使用
在这里我仅仅的是对webpack做个讲解,webpack这个工具非常强大,解决了我们前端很繁琐的一些工具流程繁琐的事情.如果感兴趣的同学,还是看官网吧. 中文链接地址:https://www.webp ...
- Java并发编程之AbstractQueuedSynchronizer源码分析
为什么要说AbstractQueuedSynchronizer呢? 因为AbstractQueuedSynchronizer是JUC并发包中锁的底层支持,AbstractQueuedSynchroni ...
- dubbo原理
1,观察DubboBeanDefinitionParser 的构造方法,给它打一个断点,发现其前一步在DubboNamespaceHandler 应用启动会连续调此方法 DubboBeanDefini ...
- 第三节 深入JavaScript
函数的返回值:(把函数体内的数据传出到函数体外) 什么是函数的返回值:函数执行结果.可以没有返回值 一种函数应该只返回一种类型的值 函数传参:(与函数返回值相反,把外面数据传入函数体内) 可变参(不定 ...
- spring总结之一(spring开发步骤、bean对象的管理、bean生命周期)
###spring 1.概念:开源,轻量级,简化开发的企业级框架. 开源:免费,发展快. 轻量级:占内存小. 简化开发:通用的功能封装,提高程序员的开发效率.--------------------- ...