1. 程式人生 > 其它 >Spring整合Redis分散式鎖

Spring整合Redis分散式鎖

1.導包

<spring.boot.version>2.2.6.RELEASE</spring.boot.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.2</version>
</dependency>

2.工具類

@Slf4j
@Component
public class RedisUtils {


    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 上鎖 將鍵值對設定一個指定的時間timeout.
     *
     * @param key
     * @param timeout 鍵值對快取的時間,單位是秒
     * @return 設定成功返回true,否則返回false
     */
    public boolean tryLock(String key, String value, long
timeout) { //底層原理就是Redis的setnx方法 boolean isSuccess = redisTemplate.opsForValue().setIfAbsent(key, value); if (isSuccess) { //設定分散式鎖的過期時間 redisTemplate.expire(key, timeout, TimeUnit.SECONDS); } return isSuccess; } public void del(String... key) {
if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } public Object get (String key) { if (key != null) { return redisTemplate.opsForValue().get(key); } return null; } }

3.使用

@Scheduled(cron = "*/5 * * ? * *")
    public void globalStatCache (){

        //-------------上分散式鎖開始-----------------

        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        //獲取本機ip
        String ip = addr.getHostAddress();
        //預設上鎖時間為五小時
        //此key存放的值為任務執行的ip,
        // redis_default_expire_time 不能設定為永久,避免死鎖
        boolean lock = redisUtils.tryLock(redisKey, ip, redis_default_expire_time);
        log.info("============定時任務開始==============");

        if (lock) {

            //具體程式碼.........
    
            try {
                Thread.sleep(1000*60);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            redisUtils.del(redisKey);
            log.info("============本次定時任務結束==============");
            //三個月
        }else {
            log.info("============獲得分散式鎖失敗=======================");
            ip = (String) redisUtils.get(redisKey);
            log.info("============{}機器上佔用分散式鎖,聚類任務正在執行=======================", ip);
            return;
        }


    }