👉项目官网:https://cronjob.horace.cn
👉Gitee 仓库:https://gitee.com/horacedh/cron-job
👉GitHub 仓库:https://github.com/horacedh/cron-job
一、为什么需要分布式任务调度平台?
有一个场景,需要每天凌晨 1 点执行一次统计任务,一般情况下是使用分布式锁(Redis、ZK、MySQL)等方式,保证同一时刻只有一个任务执行。整个应用中如果有多个这类任务则需要重复维护,如果扩大到整个公司的业务来看,效率将是低下的,并且以下诉求很难得到满足:
不支持任务参数的动态调整,例如某类任务需要根据特定参数做一些特性化事情的时候。
不支持分片任务,例如某类任务需要处理的数据量很大,需要分片处理,多个系统之间的协调也是难点。
较难失败重试,或失效转移,例如执行失败之后,需要重试或转移到其他节点执行。
任务执行数据难以统计,任务的执行的耗时、失败次数、执行次数等,都难以统计。
不支持任务的停止,例如在机房迁移等一些场景,需要暂时性的停止任务。
但是 Cron-Job 可以很好的解决这些问题,并且接入简单、超低延迟、可靠性高,使用起来非常方便。
二、Cron-Job 的核心优势
1. 简单易用
2. 毫秒级的调度延迟
3. 多租户支持
对于多业务线的企业,只需要部署一套任务调度平台,即可支撑多业务接入,且业务线权限之间互不干扰。
4. 用户体验与效率
用户的接入更加简单,只需要代码上打上注解,就可以完成自动注册,不需要额外的配置,只需要点击开始即可。
管理后台 UI 更加精美简洁,并优化了管理后台的交互逻辑,理解和使用更加简单。
更加全面且有结构化的官方文档,尽可能让用户一目了然,自主接入和部署。
5. 增强横向扩展能力
6. 更安全的管理后台
7. 更高效的问题排查效率
管理后台提供更多维度的日志详情,能够帮助用户更好的理解任务的执行情况,并且能够更好的排查问题。
三、Cron-Job 的架构
1. 模块架构
2. 部署架构
四、原生 Java 接入
1. 引入 maven 依赖
<!--同时提供有Gradle等各类依赖类型 https://mvnrepository.com/artifact/cn.horace.cronjob/cronjob-executor --><dependency> <groupId>cn.horace.cronjob</groupId> <artifactId>cronjob-executor</artifactId> <version>最新版本</version></dependency>
复制代码
2. 实现任务处理接口
/** * 演示任务 * Created in 2025-01-01 10:44. * * @author Horace */@TaskConfig(name = "普通测试任务", cron = "* * * * * ? ", routerStrategy = RouterStrategy.RANDOM)public class DemoCronTask implements TaskHandler { private static final Logger logger = LoggerFactory.getLogger(DemoCronTask.class); /** * 执行任务的方法 * * @param params 任务参数 * @return 任务执行结果,如果执行成功,则返回HandlerResult.success(),如果执行失败,则返回HandlerResult.fail(),返回null,也判定是失败 */ @Override public HandlerResult handle(TaskParams params) { logger.info("task handler..., params:{}", params); Random random = new Random(); int delay = random.nextInt(50); LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(delay)); return HandlerResult.success(); }}
复制代码
3. 新建启动类
/** * 示例执行器 * <p> * * @author Horace */public class ExampleExecutor { private static final Logger logger = LoggerFactory.getLogger(ExampleExecutor.class); public static void main(String[] args) { ArrayList<Object> taskObjects = new ArrayList<>(); taskObjects.add(new DemoCronTask()); ExecutorConfig config = ExecutorConfig.Builder.newBuilder(taskObjects) .address("http://127.0.0.1:9527") .tenant("horace") .appName("example-executor") .appDesc("普通示例执行器") .tag("common") .signKey("7d890a079948b196756rtf5452d2245t") .build(); CronJobExecutorClient.init(config).start(); }}
复制代码
address:这里指定的是调度器的地址,如果是本地单节点测试,则指定地址+端口的方式是;如果是线上集群部署,则指定的是 Nginx 地址。
tenant:租户的代码,一般是租户的英文名称。
appName:应用名称,一般是应用的英文名称。
appDesc:应用描述,应用的中文描述,后续在管理平台中可以看到。
tag:标签,用于区分同个应用下的不同执行器,如无需求,则不配置即可。
signKey:签名密钥,用于验证执行器的身份,必须和调度器配置的签名密钥一致。
五、SprintBoot 版本接入
1. 引入 maven 依赖
<!--同时提供有Gradle等各类依赖类型 https://mvnrepository.com/artifact/cn.horace.cronjob/cronjob-executor-starter --><dependency> <groupId>cn.horace.cronjob</groupId> <artifactId>cronjob-executor-starter</artifactId> <version>最新版本</version></dependency>
复制代码
2. 实现任务处理接口
/** * 演示任务 * * @author Horace */@Component@TaskConfig(name = "Spring测试任务", cron = "* * * * * ? ", routerStrategy = RouterStrategy.RANDOM)public class DemoCronTask implements TaskHandler { private static final Logger logger = LoggerFactory.getLogger(DemoCronTask.class);
/** * 执行任务的方法 * * @param params 任务参数 * @return 任务执行结果,如果执行成功,则返回HandlerResult.success(),如果执行失败,则返回HandlerResult.fail(),返回null,也判定是失败 */ @Override public HandlerResult handle(TaskParams params) { logger.info("task handler..., params:{}", params); Random random = new Random(); int delay = random.nextInt(200); LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(delay)); return HandlerResult.success(); }}
复制代码
注意:这里的任务类一定要打上 Spring 的注解,可以是 @Component,把对象实例交给 Spring 管理。
3. 新建配置类
/** * Created in 2025-01-01 21:00. * * @author Horace */@Configurationpublic class AppConfig { private static final Logger logger = LoggerFactory.getLogger(AppConfig.class);
/** * 自定义配置 * * @return */ @Bean public ExecutorStarterConfig cronJobExecutorStarterConfig() { ExecutorStarterConfig config = new ExecutorStarterConfig(); config.setAddress("http://127.0.0.1:9527"); config.setTenant("horace"); config.setAppName("example-executor-starter"); config.setAppDesc("Spring示例执行器"); config.setTag("common"); config.setSignKey("7d890a079948b196756rtf5452d2245t"); return config; }}
复制代码
注意:需要在启动类上加上 @EnableCronJob 注解,开启 CronJob 的自动配置。
放一张调度平台首页的图片~
👉项目官网:https://cronjob.horace.cn
👉Gitee 仓库:https://gitee.com/horacedh/cron-job
👉GitHub 仓库:https://github.com/horacedh/cron-job
评论