任意时间定时任务+reids实现 (后续的优化)

####注小批量   (对上个版本的优化)

@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);

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值