当前位置:   article > 正文

Redis分布式锁Redisson_redisson锁

redisson锁

分布式锁

分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。

分布式锁的核心是实现多进程之间互斥,而满足这一点的方式有很多,常见的有三种:

在这里插入图片描述

不可重入Redis分布式锁

原理:利用setnx的互斥性;利用ex避免死锁;释放锁时判断线程标示 缺陷:不可重入、无法重试、锁超时失效

实现分布式锁时需要实现的两个基本方法:

  • 获取锁:
    • 互斥:确保只能有一个线程获取锁

      • 添加锁,利用setnx的互斥特性
      • 添加锁过期时间,避免服务宕机引起的死锁

在这里插入图片描述

  • 释放锁
    • 手动释放
    • 超时释放:获取锁时添加一个超时时间
# 释放锁,删除即可
DEL key
  • 1
  • 2

分布式锁实现,满足:

在获取锁时存入线程标示(可以用UUID表示)
在释放锁时先获取锁中的线程标示,判断是否与当前线程标示一致
如果一致则释放锁
如果不一致则不释放锁

Redisson

https://github.com/redisson/redisson

快速入门

可重入的Redis分布式锁

原理:利用hash结构,记录线程标示和重入次数;利用watchDog延续锁时间;利用信号量控制锁重试等待
缺陷:redis宕机引起锁失效问题

依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.6</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

配置Redisson客户端:


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedisConfig {

    @Bean
    public RedissonClient redisClient() {

        Config config = new Config();
        config.useSingleServer().setAddress("redis://47.96.16.107:6379").setPassword("654321");

        return Redisson.create(config);
    }
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

使用

@Resource
private RedissonClient redissonClient;

@Test
void testRedisson() throws InterruptedException {
    // 获取锁(可重入),指定锁的名称
    RLock lock = redissonClient.getLock("anyLock");
    // 尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位     
    boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
    // 判断释放获取成功     
    if (isLock) {
        try {
            System.out.println("执行业务");
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Redisson的multiLock

配置类

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedisConfig {

    @Bean
    public RedissonClient redisClient1() {

        Config config = new Config();
        config.useSingleServer().setAddress("redis://47.96.16.107:6379").setPassword("654321");

        return Redisson.create(config);
    }
    
    @Bean
    public RedissonClient redisClient2() {

        Config config = new Config();
        config.useSingleServer().setAddress("redis://47.96.16.107:6380").setPassword("654321");

        return Redisson.create(config);
    }
    
    @Bean
    public RedissonClient redisClient3() {

        Config config = new Config();
        config.useSingleServer().setAddress("redis://47.96.16.107:6381").setPassword("654321");

        return Redisson.create(config);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

multiLock

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;


@Slf4j
@SpringBootTest
class SimpleLockTest {


    @Resource
    private RedissonClient redissonClient1;

    @Resource
    private RedissonClient redissonClient2;

    @Resource
    private RedissonClient redissonClient3;

    @Test
    void testRedisson() throws InterruptedException {

        RLock lock1 = redissonClient1.getLock("apple");
        RLock lock2 = redissonClient2.getLock("apple");
        RLock lock3 = redissonClient3.getLock("apple");

        RLock lock = redissonClient1.getMultiLock(lock1, lock2, lock3);

//        // 获取锁(可重入),指定锁的名称
//        RLock lock = redissonClient.getLock("anyLock");
        // 尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位
        boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
        // 判断释放获取成功
        if (isLock) {
            try {
                System.out.println("执行业务");
            } finally {
                // 释放锁
                lock.unlock();
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/710710
推荐阅读
相关标签
  

闽ICP备14008679号