# htliu-job **Repository Path**: kongxinmark/htliu-job ## Basic Information - **Project Name**: htliu-job - **Description**: 定时任务执行器 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2022-10-20 - **Last Updated**: 2023-03-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # htliu-job #### 介绍 **redis版是分布式调度,依赖redisson的自动续期机制,多台机器运行时,确保某台机器执行过程中,突然宕机任务不会丢失。多台机器同时抢占服务保证不会重复执行,某个任务执行时间过长,利用redis看门狗技术保证此任务不会重复执行。利用rocketMQ的订阅发布机制,保证用户请求某一台机器去删除,新增,暂停任务,其他机器能监听到后同步** 。 dev版为单机版。 与xxljob的区别,xxljob是一种调度任务的框架,调度机和业务执行机器严格区分开。htliu-job是一种抢占执行任务的框架,不存在调度机,多台业务执行机抢占去执行任务。htliu-job是一种智能的低延迟高性能,少占CPU(基于 **红黑树** ,第10,11,12点的实现可以减少对CPU的占用率,尽量腾出CPU),基于 **日级时间轮** 实现的海量(单机日跑1千万左右秒级以下任务)定时任务执行器兼本地消息中间件(本地同步执行时间过长需转异步执行)。基本特性介绍: 1.支持threadlocal数据还原执行环境; 2.支持cron表达式; 3.支持组合任务,即任务附加其他的任务,使用编程式事务,确保任务组合的事务一致;现只支持一层任务的附加,远期支持任务的拖拽组合。 4.支持任务的删除,修改,暂停和恢复; 5.支持任务的指定执行次数,重复间隔时间执行; 6.支持非cron表达式,人性化的执行日期,间隔时间,执行次数的设置; 7.支持查看当前服务器运行状态和卡顿总秒数; 8.支持查看正在运行和等待运行的任务状态; 9.支持流式读取数据库,防止OOM; 10.智能检测当天的任务是否全部完成,如果完成就休眠让出CPU,一直到新增当天的任务,才唤醒去执行。 11.智能检测下一个任务执行时间,休眠到下一个任务执行时间让出CPU,而不是每秒去检测。 12.智能检查空闲时间,补偿执行以前没有执行的任务 第10,11,12是市面上流行的定时任务执行框架属不具有的特性,防止了呆傻无限循环占用CPU 秒分布器SecondDistributor基于红黑树的实现,可以探测当前秒以后的哪些秒 上有任务 ![输入图片说明](%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_1662713237201.png) #### 软件架构 现只支持当前项目和业务项目部署在同一台机器运行,远期实现分布式部署和负载均衡调度。 ![输入图片说明](%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16627154806555.png) #### 安装教程 1. 执行sql.txt的脚本 #### 使用说明 @TaskHandler为类上定时任务的固定注解,@TimingTask为方法上定时任务设置的固定任务注解,timingTaskType为AUTO代表是启动就开启的任务,MANUAL代表被调用才会开启的任务。 dynamicParamSolver用来获取定时任务的执行时间,和业务相关的businessId,通常为主表的objectId 1. 声明式任务:支持项目启动自动加入任务,使用方法如下 @TaskHandler public class HelloAutoService { @TimingTask(dynamicParamSolver = "dynamicSolver", timingTaskType = TimingTaskType.AUTO) public String hello() { System.out.println("------------hello---------------"); return "hello world"; } public TaskExecutionBuilder dynamicSolver() { return new FixedDateTaskExecutionAdapter() { @Override public Date executionTime() { return new Date(new Date().getTime() + 30 * 1000); } @Override public String taskDesc() { return "test"; } @Override public String businessId() { return "test01"; } }; } @TimingTask(dynamicParamSolver = "dynamicSolver1", timingTaskType = TimingTaskType.AUTO) public String hello1() { System.out.println("------------hello1---------------"); return "hello world1"; } public TaskExecutionBuilder dynamicSolver1() { return new FixedDateTaskExecutionAdapter() { @Override public Date executionTime() { return new Date(new Date().getTime() + 10 * 1000); } @Override public String taskDesc() { return "test1"; } @Override public String businessId() { return "test02"; } }; } } 2. 声明式任务:支持在@TaskHandler的方法被调用时加入,当在其他controller或者service层调用了RfqCompilingJob 的start,就会走异步,start会作为定时任务去执行 @TaskHandler public class RfqCompilingJob { @Autowired private IBusinessObjectService iBusinessObjectService; @TimingTask(dynamicParamSolver = "startDynamicSolver", timingTaskType = TimingTaskType.MANUAL) public String start(String objectId, Date startDate) { System.out.println("------------start---------------" + iBusinessObjectService); return "hello world"; } public TaskExecutionBuilder startDynamicSolver(String objectId, Date startDate) { return new FixedDateTaskExecutionAdapter() { @Override public Date executionTime() { return startDate; } @Override public String taskDesc() { return "寻源编制报价开始"; } @Override public String businessId() { return objectId; } }; } @TimingTask(dynamicParamSolver = "endDynamicSolver", timingTaskType = TimingTaskType.MANUAL) public String end(String objectId, Date startDate) { System.out.println("------------hello---------------" + iBusinessObjectService) ; return "hello world"; } public TaskExecutionBuilder endDynamicSolver(String objectId, Date startDate) { return new FixedDateTaskExecutionAdapter() { @Override public Date executionTime() { return startDate; } @Override public String taskDesc() { return "寻源编制报价结束"; } @Override public String businessId() { return objectId; } }; } } 在controller调用RfqCompilingJob 就会异步去执行 @RestController @RequestMapping("/sourcing/rfq") public class RfqCompilingController { @Autowired private RfqCompilingJob rfqCompilingJob; @PostMapping("/queryDetail") public ResultValue queryDetail(@RequestParam String objectId, @RequestParam int type) { rfqCompilingJob.start(objectId, new Date(new Date().getTime() + 30000)); } } 3. 编程式任务:支持在程序中,利用代码加入,建造者模式 TwManager.getInstance().addTask(new TaskBuilder() { @Override public Date executionTime() { return new Date(new Date().getTime() + 1000); } @Override public String executionMethod() { return "run"; } @Override public String beanName() { return "person"; } @Override public Object[] args() { return new Object[]{new Teacher("xxx"), new Teacher("yyyy")}; } @Override public String taskDesc() { return "采购合同任务"; } @Override public String businessId() { return "FB0C40420DBB45019902F9A5B4C261E9"; } //间隔秒数,-1为不间隔执行 public long executionInterval() { return 2; } //执行次数 public long executionRounds() { return 1000000; } }); 4. 编程式任务:支持在程序中,利用代码加入,非建造者模式,任务类型有4种:AttachTask(附加任务) FixedDateTask(固定日期) ImmediateTask(立即执行) IntervalTask(间隔执行) FixedDateTask task1 = new FixedDateTask("1", new Date(new Date().getTime() + i * 100), "sss"); Teacher t1 = new Teacher("xxx"); Teacher t2 = new Teacher("xxx"); try { task1.createTaskMethod("run", "person", new Object[]{t1, t2}); } catch (Exception e) { e.printStackTrace(); } ![输入图片说明](%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16624525896444.png)这张表可以查看服务器运行状态,delay_cnt是服务器卡顿总秒数 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)