写在前面:
小编比较推崇成体系的学习,无论是什么样的技术,流行或者不流行,都可以形成一整套知识体系
不信的,可以来看我最近的文章
第一次见到这么齐全的redis知识图谱,老大再也不用担心我的技术
成体系的学习能给自己带来很多的帮助,无论是工作还是面试还是为了你之后的发展,今天整理这篇文章也是因为前段时间,公司要改造现有的单节点调度为分布式任务调度,所以研究了很多的相关的文档等资料,也就有了今天的文章
当时为了那个框架,本身想要省点事,研究了目前市面上主流的开源分布式任务调度框架,但是最后用起来就一个感觉:麻烦!特别是之前在一个类里写了好多个调度任务,改造起来更加麻烦。我这人又比较懒,总感觉用了别人写好的工具还要改一大堆,心里就有点不舒服。
但是绝对不能拒绝说分布式调度系统的重要性,中途插一句啊:
分布式调度系统的重要性
分布式调度在互联网企业中占据着十分重要的作用,尤其是电子商务领域,由于存在数据量大、高并发的特点,对数据处理的要求较高,既要保证高效性,也要保证准确性和安全性,相对比较耗时的业务逻辑往往会从中剥离开来进行异步处理。
个人研发
于是我就想自己写一个框架,毕竟自己觉得分布式任务调度在所有分布式系统中是最简单的,因为一般公司任务调度本身不可能同时调度海量的任务,很大的并发,改造成分布式主要还是为了分散任务到多个节点,以便同一时间处理更多的任务。
后面有一天,我在公司前台取快递,看到这样一个现象:我们好几个同事(包括我)在前台那从头到尾看快递是不是自己的,是自己的就取走,不是就忽略,然后我就收到了启发。这个场景类比到分布式调度系统中,我们可以认为是快递公司或者快递员已经把每个快递按照我们名字电话分好了快递,我们只需要取走自己的就行了。但是从另外一个角度看,也可以理解成我们每个人都是从头到尾看了所有快递,然后按照某种约定的规则,如果是自己的快递就拿走,不是自己的就忽略继续看下一个。如果把快递想象成任务,一堆人去拿一堆快递也可以很顺利的拿到各自的快递,那么一堆节点自己去取任务是不是也可以很好的处理各自的任务呢?
就在这个灵感之后,我便开始行动,关键代码附上
package com.rdpaas.task.scheduler;import com.rdpaas.task.common.*;
import com.rdpaas.task.config.EasyJobConfig;
import com.rdpaas.task.repository.NodeRepository;
import com.rdpaas.task.repository.TaskRepository;
import com.rdpaas.task.strategy.Strategy;
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Date; import java.util.List;
import java.util.concurrent.*;
/** * 任务调度器 *
@author rongdi *
@date 2019-03-13 21:15 */
@Component
public class TaskExecutor {
private static final Logger logger = LoggerFactory.getLogger(TaskExecutor.class);
@Autowired
private TaskRepository taskRepository;
@Autowired
private NodeRepository nodeRepository;
@Autowired
private EasyJobConfig config;
/** * 创建任务到期延时队列 */
private DelayQueue
> taskQueue = new DelayQueue<>(); /** * 可以明确知道最多只会运行2个线程,直接使用系统自带工具就可以了 */
private ExecutorService bossPool = Executors.newFixedThreadPool(2);
/** * 声明工作线程池 */
private ThreadPoolExecutor workerPool;
@PostConstruct
public void init() {
/** * 自定义线程池,初始线程数量corePoolSize,线程池等待队列大小queueSize,当初始线程都有任务,并且等待队列满后 * 线程数量会自动扩充最大线程数maxSize,当新扩充的线程空闲60s后自动回收.自定义线程池是因为Executors那几个线程工具 * 各有各的弊端,不适合生产使用 */
workerPool = new ThreadPoolExecutor(config.getCorePoolSize(), config.getMaxPoolSize(), 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(config.getQueueSize()));
/** * 执行待处理任务加载线程 */
bossPool.execute(new Loader());
/** * 执行任务调度线程 */
bossPool.execute(new Boss());
} class Loader implements Runnable
好了,至此,基本结束,但是,就像java的设计模式一样,平时很少能用到那么多,但是你不会可以吗?答案是一定的,肯定不行,那么同样的,我们是公司业务允许我大展身手可以自己发展,但是要是公司不能让你自由发挥呢?还是要用现成的不是吗?接下来看一下我整理的比较常用的分布式任务调度系统
国产平台介绍
1、opencron
https://gitee.com/benjobs/ope...
opencron 是一个功能完善且通用的开源定时任务调度系统,拥有先进可靠的自动化任务管理调度功能,提供可操作的 web 图形化管理满足多种场景下各种复杂的定时任务调度,同时集成了 linux 实时监控、webssh 等功能特性。
你是否有定时执行任务计划的需求,需要在linux的crontab里一一定义任务?
- 需要在每台linux服务器的crontab里一一定义任务;
- 任务的执行监控太不方便了;
- 得登录到每台机器查看定时任务的运行结果,机器一多简直是一种灾难;
- 对于多台机器协同处理一个任务很麻烦,如何保证多台机器上的任务按顺序依次执行?
- 当任务运行失败,要重新执行,还得重新定义下执行时间,让其重跑,重跑完成了还得改回正常时间;
- 正在运行的任务要kill掉很麻烦,查看进程然后才能kill ......
2、LTS
https://gitee.com/hugui/light...
LTS,light-task-scheduler,是一款分布式任务调度框架, 支持实时任务、定时任务和 Cron 任务。有较好的伸缩性和扩展性,提供对 Spring 的支持(包括 Xml 和注解),提供业务日志记录器。支持节点监控、任务执行监、JVM 监控,支持动态提交、更改、停止任务。
完整的示例代码:
https://github.com/ltsopensou...
3、XXL-JOB
https://gitee.com/xuxueli0323...
http://www.xuxueli.com/xxl-job
XXL-JOB 是一个轻量级分布式任务调度框架,支持通过 Web 页面对任务进行 CRUD 操作,支持动态修改任务状态、暂停/恢复任务,以及终止运行中任务,支持在线配置调度任务入参和在线查看调度结果。
4、Elastic-Job
https://gitee.com/elasticjob/...
Elastic-Job 是一个分布式调度解决方案,由两个相互独立的子项目 Elastic-Job-Lite 和 Elastic-Job-Cloud 组成。定位为轻量级无中心化解决方案,使用 jar 包的形式提供分布式任务的协调服务。支持分布式调度协调、弹性扩容缩容、失效转移、错过执行作业重触发、并行调度、自诊断和修复等等功能特性。
5、Uncode-Schedule
https://gitee.com/uncode/unco...
Uncode-Schedule 是基于 ZooKeeper + Quartz / spring task 的分布式任务调度组件,确保每个任务在集群中不同节点上不重复的执行。支持动态添加和删除任务,支持添加 ip 黑名单,过滤不需要执行任务的节点。
功能概述:
- 基于zookeeper+spring task/quartz/uncode task的分布任务调度系统。
- 确保每个任务在集群中不同节点上不重复的执行。
- 单个任务节点故障时自动转移到其他任务节点继续执行。
- 任务节点启动时必须保证zookeeper可用,任务节点运行期zookeeper集群不可用时任务节点保持可用前状态运行,zookeeper集群恢复正常运期。
- 支持动态添加、修改和删除任务,支持任务暂停和重新启动。
- 添加ip黑名单,过滤不需要执行任务的节点。
- 后台管理和任务执行监控。
- 支持spring-boot,支持单个任务运行多个实例(使用扩展后缀)。
模块机构:
6、Antares
https://github.com/ihaolin/an...
Antares 是一款基于 Quartz 机制的分布式任务调度管理平台,内部重写执行逻辑,一个任务仅会被服务器集群中的某个节点调度。用户可通过对任务预分片,有效提升任务执行效率;也可通过控制台 antares-tower 对任务进行基本操作,如触发,暂停,监控等。
Antares整体架构:
Antares中的任务状态机:
觉得整理的还算齐全的,欢迎点赞+关注给小编一点动力,后期会不断更新相应的文章,谢谢
转发分享给更多人,然后可以私信“资料”获取你需要的资料哦,只要你来,只要我有,小编绝不吝啬
关注公众号:Java架构师联盟,每日更新技术好文