####注小批量 (对上个版本的优化)
@Scheduled(fixedRate = 60000) // 每 1 分钟执行一次
public void checkTasks() {
System.out.println("每1分钟执行1次");
// 获取当前时间戳(毫秒)
long now = System.currentTimeMillis();
// 获取所有已到期的任务
Set<Object> taskIds = redisTemplate.opsForZSet().rangeByScore(TASK_KEY, 0, now); // score <= 当前时间
if (taskIds != null && !taskIds.isEmpty()) {
for (Object taskIdObj : taskIds) {
if (taskIdObj instanceof String) {
String taskId = (String) taskIdObj;
// 获取任务的时间
Double taskTimeStamp = redisTemplate.opsForZSet().score(TASK_KEY, taskId);
if (taskTimeStamp != null && taskTimeStamp <= now) {
// 时间到达,立即执行任务
executeTask(taskId);
// 执行完后,从 Redis 中移除任务
redisTemplate.opsForZSet().remove(TASK_KEY, taskId);
} else {
// 任务尚未到达,检查任务剩余时间
long remainingTime = taskTimeStamp.longValue() - now; // 任务距离当前时间的剩余时间
if (remainingTime < 60000) { // 如果任务剩余时间小于 1 分钟
System.out.println("Task " + taskId + " is scheduled to run in less than 1 minute. Scheduling immediately.");
scheduler.schedule(() -> executeTask(taskId), remainingTime, TimeUnit.MILLISECONDS); // 立即调度任务
} else {
// 如果任务时间距离现在还有较长时间,跳过
System.out.println("Task " + taskId + " scheduled for " + LocalDateTime.ofInstant(Instant.ofEpochMilli(taskTimeStamp.longValue()), ZoneId.systemDefault()) + " is not yet due.");
}
}
}
}
} else {
System.out.println("没有待执行的任务");
}
}
// 执行任务的逻辑
private void executeTask(String taskId) {
System.out.println("Executing task with ID: " + taskId + " at " + LocalDateTime.now());
}
// 存储任务的时间到 Redis
public void saveTaskTime(String taskId, String taskTime) {
System.out.println("-----------------------saveTaskTime");
// 解析任务时间字符串为 LocalDateTime 对象
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime taskTimeParsed = LocalDateTime.parse(taskTime, formatter);
// 转换为时间戳(毫秒)
long timestamp = taskTimeParsed.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
// 使用 SortedSet 存储任务时间,score 为时间戳,member 为 taskId
redisTemplate.opsForZSet().add(TASK_KEY, taskId, timestamp);
}