一个轻量级、高性能、支持延时任务的任务管理器
源代码地址
特性
-
支持即时任务和延时任务 可以单例部署或集群部署 每个任务都有绑定的执行器,指向真正执行任务的代理方
轻量
极少的中间件依赖
-
在单例模式下,只依赖mysql/pgsql 在集群模式下,增加了对redis的依赖 资源消耗低,内存占用通常低于 300MB
安全性
-
每一个改动都有审计日志 使用token进行认证
运行
已测试的依赖版本
-
Java 8 MySQL 8.0, PostgreSQL 12 Redis 6.0
创建数据表
见
配置数据源
修改 application.yml
性能
主机配置
-
OS: Win10 CPU: 6核 12线程 内存:16G 固态硬盘
MySQL 8 , 执行器类型
-
stdout,任务数量1000,耗时约1s http, 127.0.0.1:8080/test/echo,任务数量1000,耗时约1s
PostgreSQL 12 , 执行器类型
-
stdout,任务数量1000,耗时1s以内 http, 127.0.0.1:8080/test/echo,任务数量1000,耗时约1s
概念
执行器
真正执行任务的代理,例如一个http服务.
协调者
负责协调时钟,向JSD分配任期
Job scanner dispatcher(JSD)
接受协调者分发的任期,分配给JS
Job scanner(JS)
扫描任务序列,将任务ID投递至任务队列
Job queue(JQ)
保存将要执行的任务ID,FIFO
任务消费
从JQ中取出任务ID,获取绑定的执行器并调用执行服务。
利用线程池提升消费速度。
延时任务的实现
任务被一个长整形的唯一ID标识,该ID与执行时间是正相关的.
任务ID的计算基于执行时间和一个自增的序列号。假定任务的执行时间戳为1632041675,序列号为1,任务ID计算如下
1632041675 << 20 + 1
拿到一个时间戳,我们就可以计算出该时间戳对应的最小ID值和最大ID值
1632041675 << 20 + 1 1632041675 << 20 + (1 << 20 - 1)
真相即将揭晓.
任务存储在一张表中,该表的主键是任务ID. 当时钟到达一个时间戳时,JS开始基于计算出的最小ID和最大ID进行范围扫描
就是这样!
集群的实现
集群使用Redis进行信息同步。
在集群中,每个节点都可以是协调者或跟随者,并且所有的节点都是平等的。
跟随者负责消费任务队列,并随时准备成为协调者。
协调者同时也是跟随者,但需要做额外的工作。它还负责扫描任务表,将任务ID投递到队列。
协调者的任期很短,通常为1秒钟。
源代码地址
下一篇:
mysql进阶篇之存储引擎(一)