天天看点

【Redis】之 Redisson初探

文章目录

    • 一、简介
      • (1)`SpringBoot2.x`配置`Redisson`注意事项
    • 二、`Demo` 测试
      • (1)配置 + 代码
      • (2)`nginx` 负载均衡
      • (3)压测
    • 三、问题
      • (1)若获得锁后,业务逻辑长时间没有释放锁?
      • (2)若获得锁后,业务逻辑没有完成而锁过期(释放)?数据不一致?
      • (3)若要释放锁时,进程挂了等等?
      • (4)等待锁时,超时后,还没获得锁,之后业务该怎么办?

一、简介

Based on high-performance async and lock-free Java Redis client and Netty framework.

基于高能性异步锁自由Java Redis客户端 和 Netty框架

参数配置:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95

(1)

SpringBoot2.x

配置

Redisson

注意事项

SpringBoot2.x

默认使用

Lettuce

冲突:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

// 会与下面这个冲突,二者存一
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.11.2</version>
</dependency>
           

若加入

redisson-spring-boot-starter

,里面会排除

lettuce

// 此配置会排除 Lettuce,
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
           

二、

Demo

测试

(1)配置 + 代码

  1. pom.xml

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.11.2</version>
</dependency>
           
  1. RedisConfig.java

@Configuration
public class RedisConfig {

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);

        return Redisson.create(config);
    }
}
           
  1. Demo
@RestController
@RequestMapping("/redisson")
public class RedissonController {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisDao redisDao;

    @RequestMapping(value = "/sku/init")
    public String initSku() {

        redisDao.setString("product_sku", "4000");

        return "初始化库存成功";
    }

    @RequestMapping("/sku/reduce")
    public void reduce() {
        RLock lock = redissonClient.getLock("product_sku");
        boolean locked = false;
        try {
            locked = lock.tryLock(0, 10, TimeUnit.SECONDS);
            if (locked) {
                System.out.println("获取锁成功。。。");
            } else {

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

            int sku = Integer.parseInt(redisDao.get("product_sku"));

            if (--sku < 0) {
                System.out.println("库存不足。。。");
                return;
            }

            redisDao.setString("product_sku", Integer.toString(sku));

            System.out.println("减库存成功: " + sku);

        } catch (InterruptedException e) {
            e.printStackTrace();

        } finally {
            if (!locked) {
                System.out.println("获取锁失败。。。");
            }
            lock.unlock();
        }
    }
}
           

(2)

nginx

负载均衡

  1. sudo docker pull nginx

  2. sudo docker run --name=nginx -p 8000:80 -d nginx

访问

localhost:8000

,即可访问 nginx 页面
  1. 挂载运行
# ro:只读
sudo docker run --name=nginx -p 80:80 \
-v /home/donald/Documents/Docker/Nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-d nginx
           
upstream redis {
        server 192.168.0.143:8080;
        server 192.168.0.143:8081;
    }

    server {
        listen       80;
        server_name  localhost;
        location / {
            proxy_pass   http://redis;
        }
    }
           
  1. sudo docker exec -it nginx bash

    运行

(3)压测

采用

ab

压测

sudo docker run --rm jordi/ab -k -c 200 -n 4000 http://192.168.0.143:8080/redisson/sku/reduce
           
  1. 使用

    lock.lock( 10, TimeUnit.SECONDS);

    在此压测情况下,库存可刚好消费完

压测结果如图:

【Redis】之 Redisson初探
  1. 使用

    locked = lock.tryLock(1, 10, TimeUnit.SECONDS);

    在此压测情况下,库存大部分情况下均消费不完

压测结果如图:

【Redis】之 Redisson初探

且有如下异常:

【Redis】之 Redisson初探

三、问题

如图:

【Redis】之 Redisson初探

(1)若获得锁后,业务逻辑长时间没有释放锁?

(2)若获得锁后,业务逻辑没有完成而锁过期(释放)?数据不一致?

(3)若要释放锁时,进程挂了等等?

(4)等待锁时,超时后,还没获得锁,之后业务该怎么办?

继续阅读