目前正在着手开发一款功能全面的接口自动化测试平台,该平台将涵盖登录、用户管理、权限控制、项目管理、用例管理、测试数据管理、测试报告生成、任务调度、缺陷跟踪以及系统配置等多个核心模块。在测试过程中,我们会用到定时任务,比如:定时更新bug状态等。所以我们本篇内容介绍一个定时任务的功能实现。
技术选型
- 后端:采用Java作为主要开发语言。
- 前端:使用VUE框架进行界面展示。
- 定时任务: 使用
ScheduledTaskRegistrar
和Trigger
接口。
定时任务功能设计
为了定时任务做持久化,首先我们需要把想要执行的定时任务保存到数据库中或缓存中,保证我们服务异常或者更新、重启后,不影响已经存在的定时任务。其次我们将实现3种类型的定时任务(固定延迟、固定频率、Cron表达式)。
调度策略枚举
public enum SchedulingStrategy {
FIXED_DELAY,
FIXED_RATE,
CRON
}
任务调度工具类
@Configuration
public class TaskSchedulers {
private final Map<String, ScheduledFuture<?>> scheduledTasks = new HashMap<>();
private final TaskScheduler taskScheduler;
@Autowired
public TaskSchedulers(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
scheduler.initialize();
return scheduler;
}
public String scheduleTask(String taskId, Runnable task, SchedulingStrategy strategy, Object... strategyArgs) {
ScheduledFuture<?> future;
switch (strategy) {
case FIXED_DELAY:
long delay = (Long) strategyArgs[0];
future = taskScheduler.scheduleWithFixedDelay(task, delay);
break;
case FIXED_RATE:
long rate = (Long) strategyArgs[0];
future = taskScheduler.scheduleAtFixedRate(task, rate);
break;
case CRON:
String cronExpression = (String) strategyArgs[0];
Trigger cronTrigger = new CronTrigger(cronExpression);
future = taskScheduler.schedule(task, cronTrigger);
break;
default:
log.info("不支持的调度策略:{}", strategy);
}
scheduledTasks.put(taskId, future);
return taskId; // Optionally return the task ID for later cancellation
}
public void cancelTask(String taskId) {
ScheduledFuture<?> future = scheduledTasks.remove(taskId);
if (future != null) {
future.cancel(false);
}
}
}
使用方法介绍
scheduleWithFixedDelay
和 scheduleAtFixedRate
方法没有直接接受延迟或速率的单位,它们默认使用毫秒。如果你需要使用不同的时间单位,你可以创建一个PeriodicTrigger
并设置其周期和单位。
对于Cron表达式,使用了CronTrigger
类来封装Cron表达式。这是Spring提供的一个便利类,用于解析和计算Cron表达式的下一次执行时间。
strategyArgs
是一个可变参数列表,它允许你传递策略所需的不同数量的参数。在这个例子中,固定延迟和固定频率策略需要一个long
类型的参数(表示毫秒数),而Cron策略需要一个String
类型的参数(表示Cron表达式)。
添加了一个@Bean
注解的方法来创建TaskScheduler
实例。这确保了Spring容器将管理TaskScheduler
的生命周期。
scheduleTask
方法返回了任务ID(在这个例子中,它就是传入的taskId
),这样就可以稍后使用它来取消任务。
在应用中的任何地方注入TaskSchedulers
,调用scheduleTask
方法来调度任务。
@Autowired
private TaskSchedulers taskSchedulers;
public void someMethod() {
Runnable task = () -> System.out.println("Task executed at: " + System.currentTimeMillis());
TaskSchedulers.scheduleTask("myTask", task, SchedulingStrategy.FIXED_RATE, 5000L); // 每5秒执行一次
// 或者使用Cron表达式
// TaskSchedulers.scheduleTask("myCronTask", task, SchedulingStrategy.CRON, "0/10 * * * * ?"); // 每10秒执行一次
}