使用redisson控制多个springboot实例负载同时只有一个实例执行任务

一 redisson依赖


        
            org.redisson
            redisson-spring-boot-starter
            3.23.4
        

二 定时任务代码

package com.hzf.work.task;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author: hzf
 * @create: 2024-01-25 10:11
 **/
@Component
@Slf4j
@RequiredArgsConstructor
public class TestTask {
    @Value("${server.port}")
    private Integer port;
    private final RedissonClient redissonClient;
//    private final TestService test;

    @Scheduled(fixedRate = 5000) //每5秒执行一次
    public void sayHello() throws InterruptedException {
//        定义分布式锁名称
        String locaName = "hzf";
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = now.format(formatter);
//        获取分布式锁
        RLock lock = redissonClient.getLock(locaName);
        try {
            if (lock.tryLock()) {
                //模拟任务执行时间
                Thread.sleep(4000);
                System.out.println(format + "  port" + port);
            } else {
                //没有获取到锁,说明其他服务正在执行定时任务
                System.out.println("未获取到所,其他服务正在执行定时任务");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (lock.tryLock()) {
                lock.unlock();
            }
        }
    }

}

三 结果验证

        将项目复制2-3份,修改每个项目的application.yml文件中的端口,保证每个项目运行的端口不同,将项目全部启动。查看结果如下

       当三个项目全部启动时。首先时8003端口的项目拿到了资源,并且执行了任务。剩下两个实例都没有拿到资源,所以打印未获取到所,其他服务正在执行定时任务。关掉8003服务,换成了8002实例拿到了资源,开始执行任务。再将8002实例关掉,8001实例才开始执行任务。


 

你可能感兴趣的:(spring,boot,java,spring)