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


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

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

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

    @RestController
    public class RedissonController {
        static int numTest = 0;
        @GetMapping("/test")
        public String test(){
            System.out.println("num: " + ++numTest);
            return "success"+ Math.random()*100;
        }
    }
    
    numTest: 2
    numTest: 3
    numTest: 1
    numTest: 4
    numTest: 5
    numTest: 6
    numTest: 7
    numTest: 6
    numTest: 8
    numTest: 9
    numTest: 10

    情况2- 我们使用Lock锁

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

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

    @RestController
    public class RedissonController {
        static int numLock = 0;
    
        @GetMapping("/lock")
        public String lock(){
            Lock lock = new ReentrantLock();
            lock.lock();
            try {
                System.out.println("numLock: " + ++numLock);
            } finally {
                lock.unlock();
            }
    
            return "success"+ Math.random()*100;
        }
    
    }
    numLock: 1
    numLock: 2
    numLock: 3
    numLock: 4
    numLock: 5
    numLock: 6
    numLock: 7
    numLock: 9
    numLock: 10
    numLock: 11
    numLock: 12
    numLock: 8

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

      模拟的先决条件

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

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

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

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

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

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

    @RestController
    public class RedissonController {
        @Autowired
        private RedissonClient client;
        @Autowired
        private RedisTemplate redisTemplate;
    
      //使用redisson分布式锁从redis读写数据
        @GetMapping("/redisson/lock")
        public String 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;
        }
    
    }

     

    附录 -使用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-模拟部分截图

    END

  • 相关阅读:
    理解HTTP的POST和PUT的区别
    眼见为实 — CSS的overflow属性
    Iconfont的代码使用
    JSP中contentType、pageEncoding和meta charset的区别
    在 webpack 中使用 ECharts
    MVC 中的 ViewModel
    一个简单例子理解C#的协变和逆变
    C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法
    c#打包文件解压缩
    8种主要排序算法的C#实现 (二)
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/12831586.html
Copyright © 2020-2023  润新知