SpringBoot+aop+redis分布式定时任务只一个节点执行

本文介绍了如何在SpringBoot的微服务分布式部署中,确保某个定时任务只由一个节点执行。通过自定义 Annotation、AOP 和 Redis 分布式锁,实现了节点间的任务竞争和锁机制。在代码示例中,展示了如何定义注解、创建AOP切面以及配置定时任务,确保锁在60秒后自动失效,以适应集群环境的时间同步需求。

乱写了一点代码, 原型是微服务分布式部署中,某个定时任务只需要某个节点定时跑一次就可以了,不需要所有节点都跑, 而Springboot的定时任务设置是只针对当前节点的,所以就需要加入手段去防止一下,于是有了下面的代码:

1. 自定义Annotation注解,标识了该注解的定时任务既只能由某一个节点执行

2. AOP识别标识了自定义注解的定时任务,完成执行方法前的加锁和竞争锁的功能,分布式锁由redis实现。

3. 定时任务执行方法体

【aop编程方式可以实现分布式锁方便在其他有类似功能(分布式锁)的地方使用】

直接上代码:

1. 自定义注解

import java.lang.annotation.*; 

@Target(ElementType.METHOD) // 可以在方法上注解 @Retention(RetentionPolicy.RUNTIME) // 运行时生效 

@Documented 

public @interface ScheduleLock { 

    String key(); 

    int timeout() default 10; 

}

2. AOP, 识别注解,并实现加分布式锁功能

@Component 

@Aspect 

public class RedisLockAspect { 

    @Autowired 

    StringRedisTemplate strRedis; 

    @Pointcut(value = "@annotation(org.wyq.annotation.ScheduleLock)") 

    public void scheduleLock() { } 



    @Around(value = "scheduleLock() && @annotation(lock)") 

    public Object scheduleLockFunc(ProceedingJoinPoint point, ScheduleLock lock) throws Throwable { 

        String key = lock.key(); 

        Boolean aBoolean = strRedis.opsForValue().setIfAbsent(key, UUID.randomUUID().toString(), lock.timeout(), TimeUnit.SECONDS);

         if (!aBoolean) { 

            System.out.println("获取失败"); 

            return null; 

        } 

        Object proceed = point.proceed(); 

        return proceed; 

    }

 }

3. 定时任务,锁会在60秒后自动失效,既定时任务执行只保护60秒,一般的服务器节点集群都会有时钟同步 

@Configuration 

@EnableScheduling 

public class ScheduledConfig { 

    @Scheduled(cron = "0 38 1 * * ?") 

    @ScheduleLock(key="scheduleTest", timeout = 60) 

    public void scheduleLockFunc(){ 

        System.out.println("方法体"); 

    } 

}

以上功能需要在pom中引入的包:

测试,端口不同启动3个节点,到点执行结果:

01节点获取锁失败

02节点获取锁失败

03节点获取锁成功,执行方法体

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值