Redis项目实战:分布式锁+微服务自旋

Redis 专栏收录该内容
1 篇文章 0 订阅

Redis项目实战测试

1.在分布式系统下如何控制缓存

在这里插入图片描述

2.rides锁环境搭建测试

1.在service新建service-test模块

在这里插入图片描述

2.配置application.properties

在这里插入图片描述

启动win版本的redis

3.启动类配置

在这里插入图片描述

4.controller测试

@RestController
public class TestRedis {
    @Autowired
    private RedisTemplate redisTemplate;
    //测试redis缓存
    @GetMapping("/testLock")
    public String testLock(){
        System.out.println("正在请求微服务");
        //获取缓存中的值
        String stock = redisTemplate.opsForValue().get("stock").toString();
        int i = Integer.parseInt(stock);
        if (i>0){
            i--;
            //算术运算后,设置剩余数
            redisTemplate.opsForValue().set("stock", i);
            System.out.println("商品目前剩余数量:"+i);
        }else {
            System.out.println("商品已抢完");
        }
        return "快快抢购吧";
    }
}

初始化redis中的key的值

在这里插入图片描述

5.配置nginx负载均衡

在这里插入图片描述

proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for nginx转发请求的真实ip

6.启动三个微服务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后修改端口号,启动服务
在这里插入图片描述

7.使用压力测试工具测试

下载https://www.apachehaus.com/cgi-bin/download.plx

解压后,找到安装目录下的httpd.conf,修改为自己的安装目录
在这里插入图片描述
apacheab压测工具 ,运行bin下的httpd.exe

在这里插入图片描述

再打开一个cmd进入bin目录

输入压测命令

ab -c 20 -n 100 http:nginx负载均衡/压力方法

具体命令ab -c 10 -n 100 http://localhost/testLock

8测试结果,节点存在并发

在这里插入图片描述

2. redis自带的分布式锁setnx + 微服务方法自旋处理

1.方案一:是用分布式锁加方法自旋

使用redis分布式锁,主要使用了redis中的setnx,这个方法在redisTemplate是setIfAbsent;

redis中的setnx设置相同的key只能一个,被设置了就不能被别人设置,在redisTemplate中如果设置成功会返回true,没有设置成功返回false
在这里插入图片描述

@RestController
public class TestRedis {
    @Autowired
    private RedisTemplate redisTemplate;

    //测试redis缓存中使用分布式锁
    @GetMapping("/testLockNx")
    public String testLock(){
        System.out.println("正在请求微服务");
        //设置分布式锁
        Boolean stcokLock = redisTemplate.opsForValue().setIfAbsent("stcokLock", 1, 3, TimeUnit.SECONDS);//3秒钟分布式锁过期
        //判断是否获取分布式锁的key,拿到锁就可以操作数据库(缓存)
        if (stcokLock){
            //获取缓存中的值(这边也可以是查数据库)
            String stock = redisTemplate.opsForValue().get("stock").toString();
            int i = Integer.parseInt(stock);
            if (i>0){
                i--;
                //算术运算后,设置剩余数
                redisTemplate.opsForValue().set("stock", i);
                System.out.println("商品目前剩余数量:"+i);
            }else {
                System.out.println("商品已抢完");
            }
            redisTemplate.delete("stcokLock");//操作完成后,释放分布式锁
        }else{
            //没有分布式锁,等待,进入自旋
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return testLock();//自旋
        }
        return "快快抢购吧";
    }
}

2.问题一:在当前线程删除分布式锁的同时如果正好分布式锁过期,则会删除其他线程的锁,造成并发

3.方案二:使用uuid作为值,当线程要删除时先获取值,看是否是自己的锁

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值