-
本文目的是让大家,能快速集成使用Elastic-Job框架,尽量最简单的介绍,原理相关后续另开文章梳理。
-
想系统的了解Elastic-Job,最好去看开发者手册,里面涉及 Elastic-Job介绍、快速使用、FAQ、框架优势、支持功能等。
Elastic-Job中文文档:Elastic-Job开发者手册
一、Elastic-Job是什么?
Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。
Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。
简单说它就是一个调度框架,可以帮我们定时执行某些任务。
二、为何使用它?
1.先看下SpringBoot原生定时器如何使用:
- 需要定时执行的方法使用 @Scheduled 注解,方法所在定时器类加上 @Component
@Component //启动创建实例
public class SpringBootJob {
@Scheduled(cron = "0/5 * * * * ?") //表示要定时执行该方法,参数cron是时间表达式,表示5秒执行一次
void execute(){
System.out.println("SpringBoot Job Execute..."+ new Date());
}
}
- 开启自动扫描,即SpringBoot核心启动类加上 @EnableScheduling
@SpringBootApplication
@EnableScheduling //开启对调度的支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
- 启动应用,如图成功执行调度
SpringBoot Job Execute...Sun Apr 14 01:15:10 CST 2019
SpringBoot Job Execute...Sun Apr 14 01:15:15 CST 2019
SpringBoot Job Execute...Sun Apr 14 01:15:20 CST 2019
SpringBoot Job Execute...Sun Apr 14 01:15:25 CST 2019
-
优点:使用简单,几个注解就能搞定,无需引入其他依赖。
-
缺点:不够灵活——往往生产环境中,应用会部署到多台服务器,如果某些调度任务只想同时启动1个节点(如,控制一个节点推送消息,或者全局操作某个资源等),无法优雅实现,只能通过分布式锁或者写死某个节点去触发逻辑(比如写死一个IP,执行调度时判断当前节点IP是否是配置的IP),比较麻烦。
三、如何使用?
- 引入Maven依赖(这里使用Spring配置,其他方式请参考开发者首册)
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>2.1.5</version>
</dependency>
- 新增一个Job类,实现SimpleJob 接口(Elastic-Job提供Simple、Dataflow和Script 3种作业类型,其中Simple是简单调度任务;Dataflow是流式作业,用于不间歇的处理数据,直到fetchData方法的返回值为null或集合长度为空时,作业才停止抓取;Script类型作业意为脚本类型作业;这3种作业前2种使用较多),作为调度的入口。
package com.yeomer.job;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import java.util.Date;
public class TestJob implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
System.out.println("Elastic Job 运行中 "+ new Date());
}
}
- 增加一个xml配置文件,这边不用注解的原因是,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="yeomer-job"
base-sleep-time-milliseconds="1000"
max-sleep-time-milliseconds="3000" max-retries="3" />
<!-- 配置作业-->
<job:simple id="testJob" class="com.yeomer.job.TestJob" registry-center-ref="regCenter"
cron="0/10 * * * * ?" sharding-total-count="1" sharding-item-parameters="0=A" />
</beans>
-
其中注册中心使用zookeeper;cron是时间表达式,控制调度执行频率;
-
sharding-total-count是分片数,这个参数非常重要,它表示该任务会被分成几个分片任务,分片策略有多种,默认的是平均分配的算法
如果有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]
如果一台服务分到多个分片,则会开启多个线程去同时执行调度。
- SpringBoot核心启动类引入第3步的xml
package com.yeomer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("spring-context-job.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 启动zookeeper,启动项目
Elastic Job 运行中 Wed May 08 18:37:50 CST 2019
Elastic Job 运行中 Wed May 08 18:38:00 CST 2019
Elastic Job 运行中 Wed May 08 18:38:10 CST 2019
可以看到任务已经成功运行,每隔10s触发一次。
-
优点:开发者无需关注任务调度与服务器间关系,重心可以放在业务逻辑开发上;
有服务器增加或者宕机,会在下次任务启动前,动态调整分片参数;提供了丰富的容错机制,以及监运维监控平台。 -
缺点:引入第三方依赖;jdk版本要求至少1.7(现在应该7以下的项目很少了吧)
四、demo代码下载
已上传GitHub:https://github.com/Yeomer/elastic-job-demo.git
下载运行即可。