qq交流群:
1 介绍
Elastic-Job
是一个分布式调度解决方法,由2个独立同分布的子项Elastic-Job-Lite
和Elastic-Job-Cloud
构成。Elastic-Job-Lite
精准定位为轻量无去中心化解决方法,应用jar包的方式出示分布式每日任务的融洽服务项目。 根据quartz
计划任务架构为基本的,因而具有quartz
的绝大多数作用 应用zookeeper
做融洽,调度管理中心,更为轻量 适用每日任务的分片 适用延展性扩充,能够水准拓展, 当每日任务再度运作时,会查验当今的服务器总数,再次分片,分片完毕以后才会执行每日任务 无效迁移,容错机制解决,当一台调度服务器服务器宕机或是跟zookeeper
中断连接以后,会马上终止作业,随后再寻找别的空余的调度服务器,来运作剩下的每日任务 出示运维管理页面,能够管理方法作业和注册中心。
1.1 应用情景
因为新项目为微服务架构,单控制模块很有可能在2个案例之上的总数,计时器便会出現多案例另外实行的状况。 一般计时器缺乏管理方法页面,没法监管计时器是不是实行取得成功。 目前市面上普遍的解决方法为计时器上锁的实际操作,或是选用第三方分布式计时器。 分布式计时器有多种多样计划方案,例如阿里巴巴內部的
ScheduledX
,当当的Elastic job
,本人开源系统的xxl-job
等。
1.2 作用目录
分布式调度融洽
延展性扩充缩容
无效迁移
错过了实行作业重开启
作业分片一致性,确保同一分片在分布式自然环境中仅一个实行案例
自确诊并恢复分布式不稳定导致的难题
适用并行处理调度
适用作业生命期实际操作
丰富多彩的作业种类
Spring融合及其命名空间出示
运维平台
1.3 定义
分片:每日任务的分布式实行,必须将一个每日任务拆分成好几个单独的每日任务项,随后由分布式的服务器各自实行某一个或好多个分片项。 比如:有一个遍历数据库查询某张表的作业,目前2台服务器。为了更好地迅速的实行作业,那麼每台服务器应实行作业的
50%
。 为考虑此要求,可将作业分为2片,每台服务器实行1片。作业遍历数据信息的逻辑性应是:服务器A遍历ID以合数末尾的数据信息;服务器B遍历ID以双数末尾的数据信息。 假如分为10片,则作业遍历数据信息的逻辑性应是:一片分得的分片项应是ID,而服务器A被分派到分片项0,1,2,3,4
;服务器B被分派到分片项5,6,7,8,9
,立即的結果便是服务器A遍历ID
以0-4
末尾的数据信息;服务器B遍历ID
以5-9
末尾的数据信息。
历史时间运动轨迹:
Elastic-Job
出示了恶性事件跟踪作用,可根据恶性事件定阅的方法解决调度全过程的关键恶性事件,用以查看、统计分析和监管。
1.4 封裝elasticjob
因为当当
Elastic job
处在一年间未升级环节,有关jar处在能够应用环节作用不全。充分考虑应用情景为多新项目应用,将elastic-job-lite-spring
简易封裝便于应用。
2.使用说明书:
2.1 加上依靠
ps:
具体version版本号请应用最新版本
<dependency> <groupId>com.purgeteam</groupId> <artifactId>elasticjob-spring-boot-starter</artifactId> <version>0.1.1.RELEASE</version></dependency>
2.2 配备
ps: 必须
mysql
,zookeeper
适用,请提早构建好。
配备
bootstrap.yml
或是application.yml
。
添加下列配备:
spring: elasticjob: datasource: # job必须的纪录数据库 url: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: Rtqw123OpnmER regCenter: # 注册中心 serverList: 127.0.0.1:2181 namespace: elasticJobDemo
2.3 计时器完成方式撰写
建立计时器类(唯一不一样的地区取决于将
@Scheduled
改成完成SimpleJob
插口就可以) 计时器完成方式撰写在execute
方式里。
@Slf4j@Componentpublic class MySimpleJob implements SimpleJob { // @Scheduled(cron = "0 0/1 * * * ?") @Override public void execute(ShardingContext shardingContext) { log.info(String.format("Thread ID: %s, 作业分片数量: %s, " "当今分片项: %s.当今主要参数: %s," "作业名字: %s.作业自定主要参数: %s", Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem(), shardingContext.getShardingParameter(), shardingContext.getJobName(), shardingContext.getJobParameter() )); // 分片大概以下:依据配备的分片主要参数实行相对的逻辑性 switch (context.getShardingItem()) { case 0: // do something by sharding item 0 break; case 1: // do something by sharding item 1 break; case 2: // do something by sharding item 2 break; // case n: ... } }}log:Thread ID: 66, 作业分片数量: 1, 当今分片项: 0.当今主要参数: Beijing,作业名字: PropertiesSimpleJob.作业自定主要参数: test
2.4 配备计时器
2.4.1 建立Configuration类
将
ZookeeperRegistryCenter
和JobEventConfiguration
引入。 建立JobScheduler
@Bean(initMethod = "init")
。 在mySimpleJobScheduler
方式里先根据ElasticJobUtils#getLiteJobConfiguration
获得LiteJobConfiguration
目标。 建立SpringJobScheduler
目标回到就可以。
@Configurationpublic class MyJobConfig { // job 名字 private static final String JOB_NAME = "MySimpleJob"; // 计时器cron主要参数 private static final String CRON = "0 0/1 * * * ?"; // 计时器分片 private static final int SHARDING_TOTAL_COUNT = 1; // 分片主要参数 private static final String SHARDING_ITEM_PARAMETERS = "0=Beijing,1=Shanghai,2=Guangzhou"; // 自定主要参数 private static final String JOB_PARAMETERS = "parameter"; @Resource private ZookeeperRegistryCenter regCenter; @Resource private JobEventConfiguration jobEventConfiguration; @Bean(initMethod = "init") public JobScheduler mySimpleJobScheduler(final MySimpleJob mySimpleJob) { LiteJobConfiguration liteJobConfiguration = ElasticJobUtils .getLiteJobConfiguration(mySimpleJob.getClass(), JOB_NAME, CRON, SHARDING_TOTAL_COUNT, SHARDING_ITEM_PARAMETERS, JOB_PARAMETERS); // 主要参数:1.计时器案例,2.注册中心类,3.LiteJobConfiguration, // 3.历史时间运动轨迹(不用能够省去) return new SpringJobScheduler(mySimpleJob, regCenter, liteJobConfiguration, jobEventConfiguration); }}
ElasticJobUtils#getLiteJobConfiguration
主要参数介绍:
/** * 获得 {@link LiteJobConfiguration} 目标 * * @param jobClass 计时器完成类 * @param jobName 计时器名字 * @param cron 定时执行主要参数 * @param shardingTotalCount 作业分片数量 * @param shardingItemParameters 当今主要参数 能够为null * @param jobParameters 作业自定主要参数 能够为null * @return {@link LiteJobConfiguration} */ public static LiteJobConfiguration getLiteJobConfiguration( final Class<? extends Si mpleJob> jobClass, final String jobName, final String cron, final int shardingTotalCount, final String shardingItemParameters, final String jobParameters) { ... return ...; }
2.4.2 简化Configuration类
当然也可以用下面的
@Configuration
实现简化,配置bootstrap.yml
或者application.yml
。
spring: elasticjob: scheduled: jobConfigMap: // 为map集合 PropertiesSimpleJob: // 定时器key名称 jobName: PropertiesSimpleJob // job名称 cron: 0 0/1 * * * ? // cron表达式 shardingTotalCount: 2 // 分片数量 shardingItemParameters: 0=123,1=332 // 分片参数 jobParameters: test // 自定义参数
注入
SpringJobSchedulerFactory
,在propertiesSimpleJobScheduler
方法里调用gerSpringJobScheduler
方法即可。
@Configurationpublic class PropertiesSimpleJobConfig { @Resource private SpringJobSchedulerFactory springJobSchedulerFactory; @Bean(initMethod = "init") public JobScheduler propertiesSimpleJobScheduler(final PropertiesSimpleJob job) { // 参数:1.定时器实例,2.配置名称,3.是否开启历史轨迹 return springJobSchedulerFactory.getSpringJobScheduler(job,"PropertiesSimpleJob", true); }}
2.4.3 注解方式配置(推荐方式)
ps:这个注解包含了上述方式,简化定时器注入。
继承
SimpleJob
实现方法execute
。
在
AnnotationSimpleJob
类上加入注解@ElasticJobScheduler
即可。 下面为完整注解。
@Slf4j@ElasticJobScheduler( name = "AnnotationSimpleJob", // 定时器名称 cron = "0/8 * * * * ?", // 定时器表达式 shardingTotalCount = 1, // 作业分片总数 默认为1 shardingItemParameters = "0=Beijing,1=Shanghai,2=Guangzhou", // 分片序列号和参数用等号分隔 不需要参数可以不加 jobParameters = "123", // 作业自定义参数 不需要参数可以不加 isEvent = true // 是否开启数据记录 默认为true)public class AnnotationSimpleJob implements SimpleJob { @Override public void execute(ShardingContext shardingContext) { log.info(String.format("Thread ID: %s, 作业分片总数: %s, " + "当前分片项: %s.当前参数: %s," + "作业名称: %s.作业自定义参数: %s", Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem(), shardingContext.getShardingParameter(), shardingContext.getJobName(), shardingContext.getJobParameter() )); }}
总结
分布式job可以解决多个项目同一个定时器都执行的问题,配合elastic-job控制台可以直观监控定时器执行情况等。
示例代码地址:elastic-job-spring-boot
作者GitHub: Purgeyao 欢迎关注