本篇文章在《Spring Scheduled + Redis 实现分布式定时器(一)》上演变!
新版本将引入以下内容:
- 加入Mysql做持久化管理;(作用:动态管理所有任务)
- 内置心跳检测定时器;(作用:监听有变更的任务)
流程:
- 列表内容
- 启动项目实例;
- 加载所有的自定义注解和bean信息;
- 查询数据库目前存在的任务信息;
- 将新的自定义注解加入数据库中;
- 执行心跳检测定时器;
- 心跳检测数据库中的任务是否有变更;有:执行对应动作!
说明以下要用到的类和作用:
- KyScheduledFuture: 用于记录当前正在运行的任务;
- KyTaskDetails: 关联数据库ky_task_details表的实体类,记录所有载入的任务状态;
- KyTriggerDetails: 关联数据库ky_trigger_details表的实体类,主要是记录定时规则;用于跟KyTaskDetails配对;
- KyTrigger: 自定义触发器类;里面记录了cron、syncLock、获取下一次执行时间的信息;
- KyScheduledExecution: 自定义注解的实现类;
- KyScheduledController: 动态管理任务的控制类;
- KyScheduled: 自定义注解;
- HeartBeatJob:心跳任务;
**用户只需要控制ky_task_details和ky_trigger_details两张表即可。 心跳定时器会帮我们自动触发相应的动作;
当然,如果不想使用心跳检测的方式,也可以用提供接口的方式。每次修改ky_task_details信息时,主动去调用一下接口。**
创建mysql表语句:
CREATE TABLE `ky_task_details` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`taskName` varchar(255) COLLATE utf8_bin NOT NULL,
`beanName` varchar(255) COLLATE utf8_bin NOT NULL,
`state` int(1) NOT NULL,
`triggerId` int(11) unsigned zerofill NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `ky_trigger_details` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_bin NOT NULL,
`cron` varchar(255) COLLATE utf8_bin NOT NULL,
`state` varchar(255) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
接下来分解代码:(借鉴代码的时候可能要根据项目实际情况做些改动)
KyScheduled:新增name和synclock属性;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface KyScheduled {
/**
* A cron-like expression, extending the usual UN*X definition to include
* triggers on the second as well as minute, hour, day of month, month
* and day of week. e.g. {@code "0 * * * * MON-FRI"} means once per minute on
* weekdays (at the top of the minute - the 0th second).
* @return an expression that can be parsed to a cron schedule
*/
String cron() default "";
/**
* 自定义的定时器任务名称,为空时使用对应的方法名作为任务名;
* @return ""
*/
String name() default "";
/**
* 是否使用同步锁, 默认:使用
* @return
*/
boolean synclock() default true;
}
KyScheduledFuture:
public class KyScheduledFuture {
private String cron;
private ScheduledFuture<?> future;
public KyScheduledFuture(String cron, ScheduledFuture<?> future) {
this.cron = cron;
this.future = future;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public java.util.concurrent.ScheduledFuture<?> getFuture() {
return future;
}
public void setFuture(java.util.concurrent.ScheduledFuture<?> future) {
this.future = future;
}
}
KyTaskDetails:与数据库ky_task_details表关联的实体类;
public class KyTaskDetails {
private long id; //id
private String taskName; //用户自定义的任务名
private String beanName; //redis的lockName, 也是唯一值
private KyTrigger trigger; //触发器
private KyScheduledExecution.Job job; //任务