首页 > 其他分享 >使用分布式锁实现定时任务的精确调度

使用分布式锁实现定时任务的精确调度

时间:2023-12-17 14:22:30浏览次数:28  
标签:调度 任务 duration import 定时 annotation 分布式

使用分布式锁实现定时任务的精确调度

在分布式系统中,实现定时任务的精确调度是一项具有挑战性的任务。由于分布式环境中存在多个节点,传统的定时任务可能会出现并发执行、重复执行或者错过执行的问题。为了解决这些问题,我们可以使用分布式锁来实现定时任务的精确调度。

准备工作

在开始之前,我们需要准备以下环境和工具:

  • Spring框架
  • Redis作为分布式锁的存储介质

实现步骤

1. 创建自定义注解

首先,我们需要创建一个自定义注解,用于标记需要进行定时任务调度的方法。这个注解可以包含一些属性,用于配置定时任务的执行规则和其他参数。例如,我们可以添加cron属性来指定定时任务的执行时间表达式,以及duration属性来指定预期任务时长。此注解集成Scheduled,使其天然继承Scheduled的特性,使我们不再关系定时触发的细节。

import org.springframework.core.annotation.AliasFor;
import org.springframework.scheduling.annotation.Scheduled;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Scheduled
public @interface DistributedScheduled {

    @AliasFor(annotation = Scheduled.class, attribute = "cron")
    String cron() default "";

    /**
     * 任务持续时长
     */
    String duration() default "";

}

2. 创建切面类

接下来,我们需要创建一个切面类,用于拦截带有DistributedScheduled注解的方法,并实现定时任务的精确调度逻辑。在切面类中,我们可以使用Redis作为分布式锁的存储介质,并使用AOP技术来拦截目标方法。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DistributedScheduledAspect {

    @Autowired
    private RedisFatClient redisFatClient;

    @Around("@annotation(distributedScheduled)")
    public Object executeScheduledTask(ProceedingJoinPoint joinPoint, DistributedScheduled distributedScheduled) {
        String lockKey = joinPoint.getSignature().toLongString().replace(" ", "-");
        RLock lock = null;
        try {
            String duration = distributedScheduled.duration();
            long lockDuration = 30 * 1000;
            if (!duration.isEmpty()) {
                lockDuration = Long.parseLong(duration);
            } 
            lock = redisFatClient.getLock(lockDuration, lockKey);
        
            if (lock.tryLock()) {
                return joinPoint.proceed();
            } else {
                log.warn("lockKey: {}, 抢锁失败,此任务本节点不执行", lockKey);
            }
        } catch (Throwable throwable) {
            log.error("执行定时任务发生异常", throwable);
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return null;
    }
}

3. 使用自定义注解标记定时任务方法

现在,我们可以在需要进行定时任务调度的方法上使用DistributedScheduled注解来标记。可以根据需要配置cron和duration属性。

@Slf4j
@Component
public class MyScheduledTasks {

    @DistributedScheduled(cron = "0 * * * * ?", duration = "60000")
    public void myScheduledTask() {
        // 执行定时任务的逻辑
    }
}

总结

通过使用分布式锁和AOP技术,我们可以实现定时任务的精确调度。自定义注解可以灵活地配置定时任务的执行规则和参数,切面类则负责拦截目标方法并实现分布式锁的逻辑。这样,我们就能够在分布式环境中安全、可靠地执行定时任务。

标签:调度,任务,duration,import,定时,annotation,分布式
From: https://www.cnblogs.com/chenglc/p/17909037.html

相关文章

  • 鸿蒙小车之多任务调度实验
    说到鸿蒙我们都会想到华为mate60:遥遥领先!我们一直领先!我们这个小车也是采用的是鸿蒙操作系统,学习鸿蒙小车,让你遥遥领先于你的同学。@TOC前言本专栏将依次介绍鸿蒙小车的内核实验,硬件实验,wifi实验。一、什么是任务?为什么要有任务任务是操作系统(RTOS)中的基本组成单元,它们为嵌入式......
  • Kubernetes 调度场景实战指南
    Kubernetes调度是确保集群中的Pod在合适的节点上运行的关键组件。通过灵活配置调度策略,可以提高资源利用率、负载均衡和高可用性。在本文中,我们将深入研究一些实际的Kubernetes调度场景,并提供相应的配置示例和最佳实践。1.基础场景-NodeSelector场景描述:我们有一些节点标......
  • MongoDB中的分布式集群架构
    MongoDB中的分布式集群架构前言ReplicaSet副本集模式副本集写和读的特性Sharding分片模式分片的优势MongoDB分片的组件分片键chunk是什么分片的算法哈希分片范围分片总结参考MongoDB中的分布式集群架构前言前面我们了解了MongoDB中的索引,......
  • Windows电脑上的多开工具与分布式计算的关系
    在Windows电脑上,多开工具和分布式计算之间存在着一定的关系。多开工具是一类软件,可以帮助用户在一台电脑上同时打开多个相同或不同的应用程序实例,从而提高工作效率。而分布式计算则是利用多台计算机的闲置资源来共同完成复杂的计算任务,通过将任务分发到各个计算节点上并将计算结果......
  • 05-定时器
    05-定时器背景资料51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。前面介绍的独立按键、led灯都属于外设。定时器的作用用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作替代长时间的Delay,提高CPU的运行效率和处理速度...S......
  • Redis分布式锁的扩展方法
     分布式锁代码#region秒杀业务测试privatestaticreadonlystringredisConnectionStr="127.0.0.1:6379,connectTimeout=5000,allowAdmin=false,defaultDatabase=1";///<summary>///秒杀业务///</summary>priv......
  • Kafka 分布式消息系统
    文章目录消息中间件对比Kafka概述kafka安装和配置kafka入门生产者发送消息消费者接收消息Kafka高可用设计集群备份机制(Replication)备份机制(Replication)-同步方式kafka生产者详解同步发送异步发送参数详解(ack)参数详解(retries)参数详解-消息压缩kafka消费者详解消费者组消息有......
  • .net中通过定时任务框架Quartz.NET来实现定期网络状态检查
     Quartz.NET是一个用于在.NET应用程序中实现作业调度和定时任务的开源框架。它允许你在应用程序中定义和调度作业,支持复杂的调度需求,例如定时、重复、错过执行、依赖性等。下面,我将通过一个简单的实例来详细描述Quartz.NET的功能、使用方法,并提供源代码。在这个示例中,我......
  • 分布式存储
    分布式存储分布式存储的思想是什么分布式存储的思想是将数据分散存储在多个节点上,以提高数据的可靠性、可扩展性和性能。它基于以下几个核心思想:数据分散:将数据切分成多个块或对象,并将它们存储在不同的节点上。这样可以避免单点故障,提高系统的可靠性。冗余备份:为了保证数......
  • crontab定时任务不执行?那就试试最初的方法吧
    问题背景服务器的操作系统是centos7,没有python3,给它安装了一个miniconda3,然后发现python脚本手动执行没问题,放到定时任务里面就不执行了。定位问题查看/etc/crontab文件,内容如下。SHELL=/usr/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root#Fordetailsseem......