Java深入学习28:Redisson分布式锁的使用

摘要:
Java深入研究28:Redisson分布式锁的使用1-一般情况下,没有同步锁,使用Jmeter模拟多线程问题:发现numTest会导致重复读写(numTest=6)@RestControllerpublicclassRedissonController{staticintnumTest=0;@GetMapping(“/test”)publicStringtest(){System

Java深入学习28:Redisson分布式锁的使用

情况1-常规情况,没有任何同步锁,使用Jmeter模拟多线程

问题:结果发现numTest会出现重复读写的情况(numTest = 6)

@RestController
public classRedissonController {
    static int numTest = 0;
    @GetMapping("/test")
    publicString test(){
        System.out.println("num: " + ++numTest);
        return "success"+ Math.random()*100;
    }
}

numTest: 2numTest: 3numTest: 1numTest: 4numTest: 5
numTest: 6numTest: 7
numTest: 6numTest: 8numTest: 9numTest: 10

情况2- 我们使用Lock锁

解决的问题:单服务的情况下,解决了数据重复读写的问题

新的问题:很明显,如果是分布式服务,Lock锁是内存锁(synchronized也是),还是会出现重复读物数据的情况

@RestController
public classRedissonController {
    static int numLock = 0;

    @GetMapping("/lock")
    publicString lock(){
        Lock lock = newReentrantLock();
        lock.lock();
        try{
            System.out.println("numLock: " + ++numLock);
        } finally{
            lock.unlock();
        }

        return "success"+ Math.random()*100;
    }

}
numLock: 1numLock: 2numLock: 3numLock: 4numLock: 5numLock: 6numLock: 7numLock: 9numLock: 10numLock: 11numLock: 12numLock: 8

情况3-使用redisson分布式锁解决分布式下高并发下,数据重复读取

模拟的先决条件

1- 使用Redis保存公有数据(数据库也行);    

2-使用Ngnix负载均衡搭建分布式服务(见附录)

3-使用Jmeter模拟并发请求(见附录)

3-1-当没有使用redisson锁时,结果如下,数据大量的重复读取

@RestController
public classRedissonController {
    @Autowired
    privateRedisTemplate redisTemplate;

//直接从redis读写数据 @GetMapping(
"/redisson") publicString redisson(){ int num = (int)redisTemplate.opsForValue().get(key); System.out.println("numRedisson: " + ++num); redisTemplate.opsForValue().set(key,num); return "success"+ Math.random()*100; } }

Java深入学习28:Redisson分布式锁的使用第1张

3-2-当使用redisson锁时,结果如下,分布式下两台服务器,数据读写正常不会重复

@RestController
public classRedissonController {
    @Autowired
    privateRedissonClient client;
    @Autowired
    privateRedisTemplate redisTemplate;

  //使用redisson分布式锁从redis读写数据
    @GetMapping("/redisson/lock")
    publicString redissonLockTest(){
        RLock testLock = client.getLock("testLock");
        testLock.lock();
        try{
            if(redisTemplate.hasKey(key)){
                int num = (int)redisTemplate.opsForValue().get(key);
                System.out.println("numRedissonLock: " + ++num);
                redisTemplate.opsForValue().set(key,num);
            }

        }finally{
            testLock.unlock();
        }
        return "success"+ Math.random()*100;
    }

}

Java深入学习28:Redisson分布式锁的使用第2张

附录 -使用Ngnix负载均衡搭建分布式服务 

1-下载并安装Nginx,参考博客,只要下载安装包,正常启动就好。  

启动Ngnix指令:在安装目录下:nginx.exe

关闭Ngnix指令:在安装目录下:taskkill /f /t /im nginx.exe

2- Ngnix负载均衡配置

upstream upstream_name{
        server 127.0.0.1:8001 weight=1;#第一台服务器
        server 127.0.0.1:8002 weight=1;#第二台服务器
    }


    server {
        listen       80;
        server_name  localhost;
        location /{
            #这个至关重要,表示代理的时候设置主机名(IP)和端口,不设置会无法转发请求,这里其实就是代理Nginx本机IP以及监听端口
            proxy_set_header Host $host:8080;
            #这个是获取到请求客户端的真实IP而不是Nginx代理机器的IP
            proxy_set_header X-Real-IP $remote_addr;
            #这个是转发
            proxy_set_header X-Forwarded-For $Proxy_add_x_forwarded_for;
            #这个名字可以随便取,只要能匹配到upstream的名字即可
            proxy_pass http://upstream_name;
}
    }

附录-使用Jmeter模拟并发请求

1-Jmeter的使用参考博客

2-模拟部分截图

Java深入学习28:Redisson分布式锁的使用第3张

END

免责声明:文章转载自《Java深入学习28:Redisson分布式锁的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇为什么文件名不能包含下列任何字符 /:*?“<>|批处理--md5校检下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

线上Redis高并发连接失败问题排查

项目背景  最近,做一个按优先级和时间先后排队的需求。用 Redis 的 sorted set 做排队队列。   主要使用的 Redis 命令有, zadd, zcount, zscore, zrange 等。   测试完毕后,发到线上,发现有大量接口请求返回超时熔断(超时时间为3s)。   Error日志打印的异常堆栈为:     redis.clien...

Redis缓存设计和问题处理

工作中做的所有项目都用到了redis,对其设计思路和问题处理做个总结。 key设计:可读性高,定义简洁,不包含特殊字符,一般使用:分隔,比如user:info:1000001,表示id为1000001的缓存key value设计:字符串不宜过长,字符串最大是512M,一般来说超过10k我们就认为他是bigkey,集合,有序集合,哈希,个数不宜太多,比如存储...

2019 2345网址导航java面试笔试题 (含面试题解析)

  本人5年开发经验、18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴、今日头条、2345网址导航等公司offer,岗位是Java后端开发,因为发展原因最终选择去了2345网址导航,入职一年时间了,也成为了面试官,之前面试了很多家公司,感觉大部分公司考察的点都差不多,趁空闲时间,将自己的心得记下来,希望能给正在找或者准备找工作的朋友提供一点帮助。...

redis分布式共享锁模拟抢单的实现

本篇内容主要讲解的是redis分布式锁,并结合模拟抢单的场景来使用,内容节点如下: jedis的nx生成锁 如何删除锁 模拟抢单动作 1.jedis的nx生成锁 对于分布式锁的生成通常需要注意如下几个方面: 创建锁的策略:redis的普通key一般都允许覆盖,A用户set某个key后,B在set相同的key时同样能成功,如果是锁场景,那就无法知道到底...

Redis集群下过期key监听

1. 前言 在使用redis集群时,发现过期key始终监听不到。网上也没有现成的解决方案。于是想,既然不能监听集群,那我可以建立多个redis连接,分别对每个redis的key过期进行监听。以上做法可能不尽人意,目前也没找到好的解决方案,如果有好的想法,请留言告知哦!不多说,直接贴我自己的代码! 2. 代码实现 关于Redis集群配置代码此处不贴,直接贴配...

Redis构建全局并发锁

Redis构建全局并发锁 https://www.cnblogs.com/FG123/p/9990336.html 谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓存,但是使用Redis仅仅作为缓存未免太大材小用了。深究Redis的原理后你会发现它有很多用途,在很多场景下能够使用它快速地解决问题。常见的用途有:分布式锁控...