本文源码:GitHub·点这里 || GitEE·点这里

一、ElasticJob简介

1、定时任务

在前面的文章中,说过QuartJob这个定时任务,被广泛应用的定时任务标准。但Quartz核心点在于执行定时任务并不是在于关注的业务模式和场景,缺少高度自定义的功能。Quartz能够基于数据库实现任务的高可用,但是不具备分布式并行调度的功能。

-> QuartJob定时任务

2、ElasticJob说明

  • 基础简介

Elastic-Job 是一个开源的分布式调度中间件,由两个相互独立的子项目 Elastic-Job-Lite 和 Elastic-Job-Cloud 组成。Elastic-Job-Lite 为轻量级无中心化解决方案,使用 jar 包提供分布式任务的调度和治理。 Elastic-Job-Cloud 是一个 Mesos Framework,依托于Mesos额外提供资源治理、应用分发以及进程隔离等服务。

  • 功能特点
分布式调度协调
弹性扩容缩容
失效转移
错过执行作业重触发
作业分片一致性,保证同一分片在分布式环境中仅一个执行实例

补刀:人家官网这样描述的,这里赘述一下,充实一下文章。

  • 基础框架结构

该图片来自ElasticJob官网。

由图可知如下内容:

需要Zookeeper组件支持,作为分布式的调度任务,有良好的监听机制,和控制台,下面的案例也就冲这个图解来。

3、分片管理

这个概念在ElasticJob中是最具有特点的,实用性极好。

  • 分片概念

任务的分布式执行,需要将一个任务拆分为多个独立的任务项,然后由分布式的服务器分别执行某一个或几个分片项。

场景描述:假设有服务3台,分3片管理,要处理数据表100条,那就可以100%3,按照余数0,1,2分散到三台服务上执行,看到这里分库分表的基本逻辑涌上心头,这就是为何很多大牛讲说,编程思维很重要。

  • 个性化参数

个性化参数即shardingItemParameter,可以和分片项匹配对应关系,用于将分片项的数字转换为更加可读的业务代码。

场景描述:这里猛一读好像很飘逸,其实就是这个意思,如果分3片,取名[0,1,2]不好看,或者不好标识,可以分别给个别名标识一下,[0=A,1=B,2=C]。

二、定时任务加载

1、核心依赖包

这里使用2.0+的版本。

<dependency><groupId>com.dangdang</groupId><artifactId>elastic-job-lite-core</artifactId><version>2.1.5</version>
</dependency>
<dependency><groupId>com.dangdang</groupId><artifactId>elastic-job-lite-spring</artifactId><version>2.1.5</version>
</dependency>

2、核心配置文件

这里主要配置一下Zookeeper中间件,分片和分片参数。

zookeeper:server: 127.0.0.1:2181namespace: es-jobjob-config:cron: 0/10 * * * * ?shardCount: 1shardItem: 0=A,1=B,2=C,3=D

3、自定义注解

看了官方的案例,没看到好用的注解,这里只能自己编写一个,基于案例的加载过程和核心API作为参考。

核心配置类:

com.dangdang.ddframe.job.lite.config.LiteJobConfiguration

根据自己想如何使用注解的思路,比如我只想注解定时任务名称和Cron表达式这两个功能,其他参数直接统一配置(这里可能是受QuartJob影响太深,可能根本就是想省事…)

@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TaskJobSign {@AliasFor("cron")String value() default "";@AliasFor("value")String cron() default "";String jobName() default "";}

4、作业案例

这里打印一些基本参数,对照配置和注解,一目了然。

@Component
@TaskJobSign(cron = "0/5 * * * * ?",jobName = "Hello-Job")
public class HelloJob implements SimpleJob {private static final Logger LOG = LoggerFactory.getLogger(HelloJob.class.getName()) ;@Overridepublic void execute(ShardingContext shardingContext) {LOG.info("当前线程: "+Thread.currentThread().getId());LOG.info("任务分片:"+shardingContext.getShardingTotalCount());LOG.info("当前分片:"+shardingContext.getShardingItem());LOG.info("分片参数:"+shardingContext.getShardingParameter());LOG.info("任务参数:"+shardingContext.getJobParameter());}
}

5、加载定时任务

既然自定义注解,那加载过程自然也要自定义一下,读取自定义的注解,配置化,加入容器,然后初始化,等着任务执行就好。

@Configuration
public class ElasticJobConfig {@Resourceprivate ApplicationContext applicationContext ;@Resourceprivate ZookeeperRegistryCenter zookeeperRegistryCenter;@Value("${job-config.cron}") private String cron ;@Value("${job-config.shardCount}") private int shardCount ;@Value("${job-config.shardItem}") private String shardItem ;/*** 配置任务监听器*/@Beanpublic ElasticJobListener elasticJobListener() {return new TaskJobListener();}/*** 初始化配置任务*/@PostConstructpublic void initTaskJob() {Map<String, SimpleJob> jobMap = this.applicationContext.getBeansOfType(SimpleJob.class);Iterator iterator = jobMap.entrySet().iterator();while (iterator.hasNext()) {// 自定义注解管理Map.Entry<String, SimpleJob> entry = (Map.Entry)iterator.next();SimpleJob simpleJob = entry.getValue();TaskJobSign taskJobSign = simpleJob.getClass().getAnnotation(TaskJobSign.class);if (taskJobSign != null){String cron = taskJobSign.cron() ;String jobName = taskJobSign.jobName() ;// 生成配置SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(JobCoreConfiguration.newBuilder(jobName, cron, shardCount).shardingItemParameters(shardItem).jobParameter(jobName).build(),simpleJob.getClass().getCanonicalName());LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(simpleJobConfiguration).overwrite(true).build();TaskJobListener taskJobListener = new TaskJobListener();// 初始化任务SpringJobScheduler jobScheduler = new SpringJobScheduler(simpleJob, zookeeperRegistryCenter,liteJobConfiguration, taskJobListener);jobScheduler.init();}}}
}

絮叨一句:不要疑问这些API是怎么知道,看下官方文档的案例,他们怎么使用这些核心API,这里就是照着写过来,就是多一步自定义注解类的加载过程。当然官方文档大致读一遍还是很有必要的。

补刀一句:如何快速学习一些组件的用法,首先找到官方文档,或者开源库Wiki,再不济ReadMe文档(如果都没有,酌情放弃,另寻其他),熟悉基本功能是否符合自己的需求,如果符合,就看下基本用法案例,熟悉API,最后就是研究自己需要的功能模块,个人经验来看,该过程是弯路最少,坑最少的。

6、任务监听

用法非常简单,实现ElasticJobListener接口。

@Component
public class TaskJobListener implements ElasticJobListener {private static final Logger LOG = LoggerFactory.getLogger(TaskJobListener.class);private long beginTime = 0;@Overridepublic void beforeJobExecuted(ShardingContexts shardingContexts) {beginTime = System.currentTimeMillis();LOG.info(shardingContexts.getJobName()+"===>开始...");}@Overridepublic void afterJobExecuted(ShardingContexts shardingContexts) {long endTime = System.currentTimeMillis();LOG.info(shardingContexts.getJobName()+"===>结束...[耗时:"+(endTime - beginTime)+"]");}
}

絮叨一句:before和after执行前后,中间执行目标方法,标准的AOP切面思想,所以底层水平决定了对上层框架的理解速度,那本《Java编程思想》上的灰尘是不是该擦擦?

三、动态添加

1、作业任务

有部分场景需要动态添加和管理定时任务,基于上面的加载流程,在自定义一些步骤就可以。

@Component
public class GetTimeJob implements SimpleJob {private static final Logger LOG = LoggerFactory.getLogger(GetTimeJob.class.getName()) ;private static final SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;@Overridepublic void execute(ShardingContext shardingContext) {LOG.info("Job Name:"+shardingContext.getJobName());LOG.info("Local Time:"+format.format(new Date()));}
}

2、添加任务服务

这里就动态添加上面的任务。

@Service
public class TaskJobService {@Resourceprivate ZookeeperRegistryCenter zookeeperRegistryCenter;public void addTaskJob(final String jobName,final SimpleJob simpleJob,final String cron,final int shardCount,final String shardItem) {// 配置过程JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration.newBuilder(jobName, cron, shardCount).shardingItemParameters(shardItem).build();JobTypeConfiguration jobTypeConfiguration = new SimpleJobConfiguration(jobCoreConfiguration,simpleJob.getClass().getCanonicalName());LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(jobTypeConfiguration).overwrite(true).build();TaskJobListener taskJobListener = new TaskJobListener();// 加载执行SpringJobScheduler jobScheduler = new SpringJobScheduler(simpleJob, zookeeperRegistryCenter,liteJobConfiguration, taskJobListener);jobScheduler.init();}}

补刀一句:这里添加之后,任务就会定时执行,如何停止任务又是一个问题,可以在任务名上做一些配置,比如在数据库生成一条记录[1,job1,state],如果调度到state为停止状态的任务,直接截胡即可。

3、测试接口

@RestController
public class TaskJobController {@Resourceprivate TaskJobService taskJobService ;@RequestMapping("/addJob")public String addJob(@RequestParam("cron") String cron,@RequestParam("jobName") String jobName,@RequestParam("shardCount") Integer shardCount,@RequestParam("shardItem") String shardItem) {taskJobService.addTaskJob(jobName, new GetTimeJob(), cron, shardCount, shardItem);return "success";}
}

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

SpringBoot2 整合ElasticJob框架,定制化管理流程相关推荐

  1. SpringBoot2 整合 JWT 框架,解决Token跨域验证问题

    本文源码:GitHub·点这里 || GitEE·点这里 一.传统Session认证 1.认证过程 1.用户向服务器发送用户名和密码. 2.服务器验证后在当前对话(session)保存相关数据. 3. ...

  2. SpringBoot2 整合Ehcache组件,轻量级缓存管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.Ehcache缓存简介 1.基础简介 EhCache是一个纯Java的进程内缓存框架,具有快速.上手简单等特点,是Hibernate中默认 ...

  3. SpringBoot2 整合MinIO中间件,实现文件便捷管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.MinIO简介 1.基础描述 MinIO是一个开源的对象存储服务.适合于存储大容量非结构化的数据,例如图片.视频.日志文件.备份数据和容器 ...

  4. SpringBoot2 整合JTA组件,多数据源事务管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.JTA组件简介 1.JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个 ...

  5. springboot2整合mysql5_SpringBoot2整合SSM框架详解

    SpringBoot2整合SSM框架详解 发布时间:2019-01-15 21:33, 浏览次数:1218 , 标签: SpringBoot SSM <>开发环境 * 开发工具:Eclip ...

  6. 复杂任务处理三部曲:系统性思维、结构化思维、流程化管理

    欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章,主要包括源码分析.实际应用.架构思维.职场分享.产品思考等等,同时欢迎大家加我个人微信「java_front」一起交流学习 1 文章概述 在处理 ...

  7. 以项目化管理有序推进企业重点工作有效落地

    企业在正常经营以及发展过程中,存在着没有执行标准.一次性的,需要运用创新思路或方法解决的,并且开展复杂度和难度均较高的工作,我们通常可称之为企业内各层级的重点工作.这些重点工作有些来自战略发展输出需求 ...

  8. 吉利发布新出行科技品牌“礼帽出行” 定位高品质定制化出行

    近日,吉利控股集团旗下LEVC发布全新出行科技品牌"礼帽出行".礼帽出行面向全年龄段人群,主打发布会上宣布,礼帽出行即日起在杭州.大连.湖州三城启动正式运营. 构建差异化优势 驱动 ...

  9. 需求评审五个维度框架分析及其带来的启示-4-需求条目化管理

    需求条目化管理是指需求的主体分条目管理,比如对于用例.用户故事.特征点的条目化列表管理,有些工具中条目称为工作项(work item).条目化管理的特征是1,状态流转实现工作流:2,条目属性字段可定制 ...

最新文章

  1. WMI技术介绍和应用——Instance/Method Provider
  2. 【vue】vue中ref用法
  3. Android Studio 简介
  4. 右边补0 润乾报表_关于润乾报表的补充说明 -
  5. 坚持,这两个字非常重要!
  6. Grails动态下拉菜单
  7. 麒麟操作系统|Linux下低延时RTMP|RTSP直播播放实现
  8. html5 textarea 限制字数,如何限制textarea的字符数为225?
  9. iPhone程序中如何生成随机数
  10. 会扫地炒菜,将来机器人当钟点工
  11. Hello CTP(七)——REM交易API
  12. 双电机智能小车装配教程(海灵智电)
  13. 使用 KNX Manufacturer Tool 编写 knx 数据库的步骤
  14. 通过驱动断链来隐藏驱动
  15. 车辆搜索 -使用triplet loss 训练车辆识别模型
  16. 服务器怎么设置自动连接wifi,笔记本无线网络连接IP地址设置(自动获取IP)
  17. 小明医声发布,看AI技术秀得飞起
  18. 谈谈你对Spring Boot的理解?
  19. /dev/null表示的意思
  20. 中国能不能写出操作系统?

热门文章

  1. thymeleaf 的 th:onclick js方法入参
  2. 4-1:C/C++内存管理
  3. c++中的运算符重载---知识点:运算符重载函数,友元函数,函数重载
  4. Java 数据结构(链表LinkedList增删改查、数组Vector、获取Vector最大值、交换Vector两成员位置、栈的实现、压栈出栈实现反转、队列Queue)
  5. vue中使用postMessage进行跨越传值
  6. 开启爬虫之路,从零开始...
  7. 关于二分类的评价指标体系
  8. MediaPlay播放Stream时出现error 38等错误的原因
  9. 堆排序可运行完整C语言,Java语言,python实现
  10. ubuntu开机时网络图标不见了且不能上网