AutoJob

动态任务调度框架
授权协议 MPL
开发语言 Java
所属分类 程序开发、 作业/任务调度
软件类型 开源软件
地区 国产
投 递 者 席兴朝
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

AutoJob是一款轻量级任务调度框架,具有分布式、全异步、易拓展、易集成等特点,提供多种任务调度模式和多种任务类型。配置丰富、拓展方便、使用简单、代码侵入性低。

一、背景

生活中,业务上我们会碰到很多有关作业调度的场景,如每周五十二点发放优惠券、或者每天凌晨进行缓存预热、亦或每月定期从第三方系统抽数等等,Spring和java目前也有原生的定时任务支持,但是其都存在一些弊病,如下:

  • 不支持集群,未避免任务重复执行的问题
  • 不支持生命周期的统一管理
  • 不支持分片任务:处理有序数据时,多机器分片执行任务处理不同数据
  • 不支持失败重试:出现异常任务终结,不能根据执行状态控制任务重新执行
  • 不能很好的和企业系统集成,如不能很好的和企业系统前端集成以及不能很好的嵌入到后端服务
  • 不支持动态调整:不重启服务情况下不能修改任务参数
  • 无报警机制:任务失败之后没有报警通知(邮箱、短信)
  • 无良好的执行日志和调度日志跟踪

基于原生定时任务的这些弊病,AutoJob就由此诞生,AutoJob为解决分布式作业调度提供了新的思路和解决方案。

二、特性

简单:简单包括集成简单、开发简单和使用简单。

集成简单:框架能非常简单的集成到Spring项目和非Spring项目,得益于AutoJob不依赖于Spring容器环境和MyBatis环境,你无需为了使用该框架还得搭建一套Spring应用。

开发简单:AutoJob开发初衷就希望具有低代码侵入性和快速开发的特点,如下在任意一个类中,你只需要在某个需要调度的任务上加上注解,该任务就会被框架进行动态调度:

@AutoJob(attributes = "{'我爱你,心连心',12.5,12,true}", cronExpression = "5/7 * * * * ?")
    public void formatAttributes(String string, Double decimal, Integer num, Boolean flag) {
        //参数注入
        AutoJobLogHelper logger = new AutoJobLogHelper();//使用框架内置的日志类
        logger.setSlf4jProxy(log);//对Slf4j的log进行代理,日志输出将会使用Slf4j输出
        logger.info("string={}", string);
        logger.warn("decimal={}", decimal);
        logger.debug("num={}", num);
        logger.error("flag={}", flag);
        //使用mapper
        mapper.selectById(21312L);
        //...
    }

使用简单:使用该框架你无需关注太多的配置,整个框架的启动只需要一行代码,如下:

//配置任务扫描包路径
@AutoJobScan({"com.yourpackage"})
//处理器自动扫描
@AutoJobProcessorScan({"com.yourpackage"})
public class AutoJobMainApplication {
    public static void main(String[] args) {
    //框架启动
    new AutoJobLauncherBuilder(AutoJobMainApplication.class).withAutoScanProcessor().build().run();
        System.out.println("==================================>系统创建完成");
 	}

}

 

得益于良好的系统架构和编码设计,你的应用启动无需过多配置,只需要一行代码

动态:框架提供API,支持任务的动态CURD操作,即时生效。

任务依赖:支持配置子任务,当父任务执行结束且执行成功后将会主动触发一次子任务的执行。

一致性:框架使用DB乐观锁实现任务的一致性,在集群模式下,调度器在调度任务前都会尝试获取锁,获取锁成功后才会进行该任务的调度。

HA(开发中):该框架支持去中心化的集群部署,集群节点通过RPC加密通信。集群节点之间会自动进行故障转移和负载均衡,

弹性增缩容(开发中):支持节点的动态上下线,同时节点支持开启保护模式,防止恶劣的网络环境下节点脱离集群。

任务失败重试:支持任务失败重试,并且可设置重试间隔。

完整的生命周期:框架提供任务完整的生命周期事件,业务可捕捉并做对应的处理。

动态调度线程池:框架使用自研的动态线程池,可灵活根据任务流量动态调整线程池核心线程和最大线程参数,节省系统线程资源,并且提供了默认的拒绝处理器,防止任务被missFire。

**异步非阻塞的日志处理:**日志采用生产者消费者模型,基于自研的内存消息队列,任务方法作为日志的生产者,生产日志放入消息队列,框架启动对应的日志消费线程进行日志处理。

实时日志:日志将会实时的进行保存,便于跟踪。

任务白名单:提供任务白名单功能,只有在白名单中的任务才允许被注册和调度,保证系统安全。

可拓展的日志存储策略:日志支持多种策略保存,如内存Cache、数据库等,可根据项目需要灵活增加保存策略,如Redis、文件等。

丰富的调度机制:支持Cron like表达式,repeat-cycle调度、子任务触发、延迟触发等,得益于良好的编码设计,用户可非常简单的新增自定义调度器,如下:

/**
 * 你的自定义调度器
 * @Author Huang Yongxiang
 * @Date 2022/08/18 14:56
 */
public class YourScheduler extends AbstractScheduler{
    public YourScheduler(AutoJobTaskExecutorPool executorPool, IAutoJobRegister register, AutoJobConfigHolder configHolder) {
        super(executorPool, register, configHolder);
    }
    
    //...调度逻辑
}

@AutoJobScan("com.example.autojob.job") @AutoJobProcessorScan("com.example.autojob") public class AutoJobMainApplication { public static void main(String[] args) { new AutoJobLauncherBuilder(AutoJobMainApplication.class) .withAutoScanProcessor() //配置你的调度器 .addScheduler(YourScheduler.class) .build() .run(); System.out.println("==================================>系统创建完成"); } }

 

任务报警:框架支持邮件报警,目前原生支持QQ邮箱、163邮箱、GMail等,同时也支持自定义的邮箱smtp服务器。

1668580284754

目前系统提供:任务失败报警、任务被拒报警、节点开启保护模式报警、节点关闭保护模式报警,当然用户也可非常简单的进行邮件报警的拓展。

丰富的任务入参:框架支持基础的数据类型和对象类型的任务入参,如Boolean,String,Long,Integer,Double等类型,对于对象入参,框架默认使用JSON进行序列化入参。

良好的前端集成性:框架提供相关API,用户可以灵活开发Restful接口接入到企业项目,无需额外占用一个进程或机器来单独运行调度中心。

内存任务:框架提供DB任务和内存任务两种类型,DB任务持久化到数据库,声明周期在数据库内记录,内存任务除了日志,整个生命周期都在内存中完成,相比DB任务具有无锁、调度快速的特点。

脚本任务:提供脚本任务的执行,如Python、Shell,SQL等。

动态分片(开发中):集群模式下框架支持任务分片,多机运行。

全异步:任务调度流程采用全异步实现,如异步调度、异步执行、异步日志等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行。

 相关资料
  • 我需要在 Spring boot java 项目中调度多个任务,并通过从数据库中获取任务执行时间的值并在运行时更新程序中的计划约会来执行任务设置。 澄清用例,我有一个 Rest API,它要求我在endpoint上发出 POST 请求,该请求包含在有关此计划的必要信息正文中,例如任务的时间和要执行的作业,发出请求后,任务在我的程序中调度并在指定的时间执行 我研究了一些技术,这些技术提供了解决方案来

  • 简介 在过去,开发者必须在服务器上为每个任务生成单独的 Cron 项目。而令人头疼的是任务调度不受源代码控制,而且必须通过 SSH 连接到服务器上来增加 Cron 项目。 Laravel 的命令调度程序允许你在 Laravel 中对命令调度进行清晰流畅的定义。并且在使用调度程序时,只需要在服务器上增加一条 Cron 项目即可。调度是在 app/Console/Kernel.php 文件的 sche

  • 基本任务调度 方案1: 通过 @Cron 注解,这个需要依赖 cron4j 框架: //1分钟执行一次 @Cron("*/1 * * * *") public class MyTask implements Runnable { @Override public void run() { System.out.println("task running...");

  • 我刚刚更新了 Play!框架到版本 2.1 和 scala 到版本 2.10... 现在我的游戏!应用程序已损坏。似乎Akka API已经发生了变化。我找不到现在使用的阿卡版本,但我认为这是最后一个版本...... 我刚刚阅读了迁移指南:http://doc.akka.io/docs/akka/2.1.0/project/migration-guide-2.0.x-2.1.x.html。 我相应地

  • 每隔一段时间需要调度任务执行,也许你想注册一个任务在客户端完成连接5分钟后执行,一个常见的用例是发送一个消息“你还活着?”到远端通,如果远端没有反应,则可以关闭通道(连接)和释放资源。 本节介绍使用强大的 EventLoop 实现任务调度,还会简单介绍 Java API的任务调度,以方便和 Netty 比较加深理解。 使用普通的 Java API 调度任务 在 Java 中使用 JDK 提供的 S

  • AUTOMATING TASKS WITH JOB SCHEDULING 像任何使用 Linux 的人一样,黑客经常有他们想要定期运行的任务、脚本或其他任务。例如,你可能希望为你的系统设置一个自动文件备份, 或者你希望像我们在第 11 章做的那样转存日志文件。另一方面,黑客可能希望每天晚上或者在他们工作或上学的时候让他们的系统运行第 8 章里的 MySQLscanner.sh 脚本。这些都是调度自