对于分布式Job的思考
引言
在清理Github的时候,发现以前写的一个简单的分布式任务分发系统ClawHub/task-distribution,使用了zk的选主与队列,调度器使用spring的ThreadPoolTaskScheduler,任务支持cron表达式。
这让我想起在这之前还封装过Quartz,那时候做的是单机版超大型应用,内部需要做调度系统。
目前在公司使用过Elastic-Job,也使用过Spring自带调度与ZK的结合,还有公司Boss系统提供的配置版本任务调度。
写这篇文章主要是简单的回忆一下Quartz与Spring的ThreadPoolTaskScheduler,还有Elastic-job。再写一下自己对分布式Job的思考。
1、quartz
官网地址:quartz-scheduler.org
1.1、简单使用
maven的pom文件:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
具体任务:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import java.time.LocalDateTime;
import java.util.Random;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetailJobData1"));
System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("triggerJobData1"));
System.out.println("HelloJob start at:" LocalDateTime.now() ", prints: Hello Job-" new Random().nextInt(100));
}
}
主调度器:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.concurrent.TimeUnit;
public class MainScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
// 2、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).usingJobData("jobDetailJobData1", "测试JobDetail上下文")
.withIdentity("job1", "group1").build();
// 3、构建Trigger实例,每隔1s执行一次
Trigger trigger = TriggerBuilder.newTrigger().usingJobData("triggerJobData1", "测试Trigger上下文")
.withIdentity("trigger1", "triggerGroup1")
.startNow()//立即生效
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)//每隔1s执行一次
.repeatForever()).build();//一直执行
//4、执行
scheduler.scheduleJob(jobDetail, trigger);
System.out.println("--------MainScheduler start ! ------------");
scheduler.start();
//睡眠
TimeUnit.MINUTES.sleep(1);
scheduler.shutdown();
System.out.println("--------MainScheduler shutdown ! ------------");
}
}
经过上面三步,执行main方法,就可以简单的实现调度任务了,下面分别介绍出现的角色。
1.2、角色介绍
1.2.1、Job和JobDetail
Job是Quartz中的任务模板,JobDetail是Job的描述,当Scheduler执行任务的时候,会根据JobDetail创建新的Job,用过之后就释放掉。
1.2.2、Trigger
触发器,描述了任务是什么时候触发执行,常用有SimpleTrigger、CronTrigger,cron表达式非常强大,基本上都是基于CronTrigger来做任务调度。
1.2.3、JobDataMap与JobExecutionContext
JobExecutionContext任务执行的上下文,JobDataMap保存上下文传输的数据。
1.1、架构原理
上面这幅图可以简单的描述Quartz核心对象之间的关系。
2、Spring的ThreadPoolTaskScheduler
底层依赖于JUC的java.util.concurrent.ScheduledExecutorService。
2.1、简单使用
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import java.time.LocalDateTime;
import java.util.Random;
public class Main {
public static void main(String[] args) {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
scheduler.initialize();
scheduler.schedule(() -> {
System.out.println("HelloJob start at:" LocalDateTime.now() ", prints: Hello Job-" new Random().nextInt(100));
}, new CronTrigger("0/1 * * * * ?"));
}
}
3、Elastic-Job
Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。
官网:elasticjob.io。
我们使用的是轻量级的使用方案:elasticjob/elastic-job-lite
官方架构图:
作业执行流程图:
我也只有使用经验,并没有深入的了解其原理,具体请参考官方文档。
4、对于分布式Job的思考
现在的Quartz也有集群版本,我还没有接触过,现在碰到的基本上都是基于Quartz的包装,比如Elastic-Job、xxl job、azkaban。
因为现在的项目基本都为分布式系统,所以对于调度系统而言,单机已经不怎么适用了。
而对于分布式调度系统,必然也有很多要求,下面讲一下我的理解:
- 任务定时完成
这个式调度系统的基本要求。 - 任务可分片
对于一些大量数据的定时任务,如果只在一台机器上执行是很吃力的,所以应该有任务分片执行的功能,将大任务拆分到多个系统上执行。 - 弹性扩容缩容
在增加或者减少节点时,任务能够自动均衡。 - 任务可配置
任务的信息可动态配置。 - 任务动态操作
任务动态地启动、暂停、终止、删除等。 - 去中心化
任务的执行与否由各个节点自己控制,但是要保证任务执行不可重复。 - 故障转移
节点发生故障时,任务自动转移。 - 任务执行记录
任务的执行信息需要有记录。
能想到这只有这么多,感觉Elastic-Job就很好用。
对于分布式Job的思考的更多相关文章
- 分布式MySQL集群方案的探索与思考
转载:http://www.infoq.com/cn/articles/exploration-of-distributed-mysql-cluster-scheme?utm_campaign=rig ...
- 京东分布式MySQL集群方案介绍
背景 数据库作为一个非常基础的系统,任何一家互联网公司都会使用,数据库产品也很多,有Oracle.SQL Server .MySQL.PostgeSQL.MariaDB等,像SQLServer/Ora ...
- spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法
spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...
- 一文教你迅速解决分布式事务 XA 一致性问题
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯云数据库团队 近日,腾讯云发布了分布式数据库解决方案(DCDB),其最明显的特性之一就是提供了高于开源分布式事务XA的性能.大型 ...
- Java分布式锁实现详解
在进行大型网站技术架构设计以及业务实现的过程中,多少都会遇到需要使用分布式锁的情况.那么问题也就接踵而至,哪种分布式锁更适合我们的项目? 下面就这个问题,我做了一些分析: 分布式锁现状: 目前几乎很多 ...
- 大型互联网公司分布式ID方案总结
ID是数据的唯一标识,传统的做法是利用UUID和数据库的自增ID,在互联网企业中,大部分公司使用的都是Mysql,并且因为需要事务支持,所以通常会使用Innodb存储引擎,UUID太长以及无序,所以并 ...
- 分布式id生成方案总结
本文已经收录自 JavaGuide (60k+ Star[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.) 本文授权转载自:https://juejin.im/post/ ...
- 分布式中的分库分表之后,ID 主键如何处理?
面试题 分库分表之后,id 主键如何处理?(唯一性,排序等) 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定 ...
- Redisson源码解读-分布式锁
前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).Redisson有一样功能是可重入的分布式锁.本文来讨论一下这个功能的特点以及源 ...
随机推荐
- 《计算机存储与外设》 1Cache存储器与虚拟存储器
初读这本书,是2020年3,4月吧,以前学的大多数处理器,balabala的,虽然也有介绍储存器的,但总是不是很详细,主要还是关注cpu等计算部件或者总线等事物,就如同这本书中所写,人们往往可以很清楚 ...
- Chrome自动格式化Json输出
对JSON格式的内容进行浏览和编辑,以树形图样式展现JSON文档,并可实时编辑 安装 Chrome商店 https://chrome.google.com/webstore/detail/json-h ...
- Python入门看这些,最详细学习书籍推荐
随着人工智能以及脚本开发火热,Python已经被推上一个非常火热的巅峰! 那么,想要学习Python却又不知道从哪里开始的朋友,看这里呀~ Python在整个编程语言来说,是比较容易上手,而且“见效” ...
- c++日志工具spdLog
c++日志工具spdLog简单使用示例代码 spdlog直接引用头文件就可以使用,这一点还是比较方便的,也是刚入门使用,下面是在源码的示例代码基础上修改测试的代码: #include <cstd ...
- 谈谈集成测试(integration testing)
对于软件开发来说,软件测试是一个几乎贯穿所有阶段的活动,所以测试的重要性毋庸置疑.不同开发组织如何在不同的产品研发阶段进行测试,也在很大程度上反映了其研发能力和质量控制能力.软件测试有很多类型,包括单 ...
- 阿里出品的最新版 Java 开发手册,嵩山版,扫地僧
说起嵩山,我就想起乔峰,想起慕容复,以及他们两位老爹在少林寺大战的场景.当然了,最令我印象深刻的就是那位默默无闻,却一鸣惊人的扫地僧啊.这次,阿里出品的嵩山版 Java 开发手册的封面就有一个扫地僧, ...
- 配置 Eureka Server 集群
简介 为了使 Eureka Server 实现高可用,我们需要为它配置集群.这样当有一台 Eureka Server 有故障时,集群中的其他 Server 可以进行代替.Eureka 集群之中的 No ...
- golang目录
基础 golang安装及vscode编辑器配置 golang基础结构 golang基础数据类型 golang复合数据结构 goalng函数 golang方法 golang接口 golang并发 gol ...
- ThinkCMF&Thinkphp 首页静态化处理
基于TP5的页面静态化教程 1.首页在控制器添加以下代码生成静态页面文件 $info = $this->buildHtml("/staticIndex", 'static', ...
- selenium入门编程总结学习于龙腾)
"""编程题打开 http://ip/ecshop/wwwroot/admin/privilege.php?act=login登录(admin/123456)点击商品管理 ...