zoukankan      html  css  js  c++  java
  • redis 分布式锁nginx测试

    分布式锁的实现方式常用的就是redis和zookeeper了,今天介绍一下redis实现分布式锁

    1.基于spring-data-redis中的redisTemplate

    直接上代码

    @Slf4j
    public class RedisLockUtils {
    
        /**
         * tryLock 默认过期时间秒, 高并发场景可以使用锁续命(定时任务每隔指定时间重新加锁设置时间)
         *
         * @param redisTemplate
         * @param key
         * @param expireTime
         * @return
         */
        public static boolean tryLock(RedisTemplate redisTemplate, String key, String clientId, Long expireTime) {
            return tryLock(redisTemplate, key, clientId, expireTime, TimeUnit.SECONDS);
        }
    
        /**
         *
         * @param redisTemplate
         * @param key
         * @param clientId UUID.randomUUID().toString() 防止高并发情况下相同的key被不同锁删除
         * @param expireTime
         * @param timeUnit
         * @return
         */
        public static boolean tryLock(RedisTemplate redisTemplate, String key, String clientId, Long expireTime, TimeUnit timeUnit) {
            Boolean success = redisTemplate.opsForValue().setIfAbsent(key, clientId, expireTime, timeUnit);
            log.info("tryLock key = {}, value = {}, expireTime = {}", key, clientId, expireTime);
            return success != null && success;
        }
    
    
        /**
         * unLock
         *
         * @param redisTemplate
         * @param key
         * @return
         */
        public static boolean unLock(RedisTemplate redisTemplate, String key, String clientId) {
            Boolean success = false;
            if (clientId.equals(redisTemplate.opsForValue().get(key))) {
                success = redisTemplate.delete(key);
            }
            log.info("unLock key = {}", key);
            return success;
        }
    
    }
    

      上述代码在并发量不大的情况下没什么大问题,但是高并发的情况下和某些资源耗时的情况下要考虑使用定时任务或者定时器进行锁续命

    2.使用开源框架redisson,基于springboot redisson框架

    DistributeLock

    public interface DistributeLock {
        RLock lock(String lockKey);
    
        RLock lock(String lockKey, int timeout);
    
        RLock lock(String lockKey, TimeUnit unit, int timeout);
    
        boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);
    
        void unlock(String lockKey);
    
        void unlock(RLock lock);
    }
    

      

    RedisDistributeLock
    @Component
    public class RedisDistributeLock implements DistributeLock {
    
        @Autowired
        RedissonClient redissonClient;
    
        @Override
        public RLock lock(String lockKey) {
            RLock rLock = redissonClient.getLock(lockKey);
            rLock.lock();
            return rLock;
        }
    
        @Override
        public RLock lock(String lockKey, int timeout) {
            RLock rLock = redissonClient.getLock(lockKey);
            rLock.lock(timeout, TimeUnit.SECONDS);
            return rLock;
        }
    
        @Override
        public RLock lock(String lockKey, TimeUnit unit, int timeout) {
            RLock rLock = redissonClient.getLock(lockKey);
            rLock.lock(timeout, unit);
            return rLock;
        }
    
        @Override
        public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
            RLock lock = redissonClient.getLock(lockKey);
            try {
                return lock.tryLock(waitTime, leaseTime, unit);
            } catch (InterruptedException e) {
                return false;
            }
        }
    
        @Override
        public void unlock(String lockKey) {
            RLock rLock = redissonClient.getLock(lockKey);
            rLock.unlock();
        }
    
        @Override
        public void unlock(RLock lock) {
            lock.unlock();
        }
    }
    

      

    RedisLockUtils
    public class RedisLockUtils {
    
        private static DistributeLock distributeLock = SpringContext.getBean("distributeLock", DistributeLock.class);
    
        /**
         * 加锁
         * @param lockKey
         * @return
         */
        public static RLock lock(String lockKey) {
            return distributeLock.lock(lockKey);
        }
    
        /**
         * 释放锁
         * @param lockKey
         */
        public static void unlock(String lockKey) {
            distributeLock.unlock(lockKey);
        }
    
        /**
         * 释放锁
         * @param lock
         */
        public static void unlock(RLock lock) {
            distributeLock.unlock(lock);
        }
    
        /**
         * 带超时的锁
         * @param lockKey
         * @param timeout 超时时间   单位:秒
         */
        public static RLock lock(String lockKey, int timeout) {
            return distributeLock.lock(lockKey, timeout);
        }
    
        /**
         * 带超时的锁
         * @param lockKey
         * @param unit 时间单位
         * @param timeout 超时时间
         */
        public static RLock lock(String lockKey, int timeout, TimeUnit unit ) {
            return distributeLock.lock(lockKey, unit, timeout);
        }
    
        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 最多等待时间
         * @param leaseTime 上锁后自动释放锁时间
         * @return
         */
        public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
            return distributeLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);
        }
    
        /**
         * 尝试获取锁
         * @param lockKey
         * @param unit 时间单位
         * @param waitTime 最多等待时间
         * @param leaseTime 上锁后自动释放锁时间
         * @return
         */
        public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
            return distributeLock.tryLock(lockKey, unit, waitTime, leaseTime);
        }
    

      

    DistributeLockRest
    @RestController
    @RequestMapping("/rest")
    public class DistributeLockRest {
        @Autowired
        Environment environment;
        private int num1 = 10;
        private int num2 = 10;
        Lock lock = new ReentrantLock();
    
        @Autowired
        DistributeLock distributeLock;
    
        @GetMapping("/test")
        public String test() {
            return environment.getProperty("server.port");
        }
    
        @RequestMapping("/distributeLock")
        public void distributeLock() {
            ExecutorService executorService = Executors.newFixedThreadPool(3);
            for (int i=0;i<10;i++) {
                executorService.submit(() -> {
                    sub1();
                    System.out.println(num1);
                });
            }
            num1=10;
            System.out.println("========");
        }
    
        @RequestMapping("/localLock")
        public void lock() {
            ExecutorService executorService = Executors.newFixedThreadPool(3);
            for (int i=0;i<10;i++) {
                executorService.submit(() -> {
                    sub2();
                    System.out.println(num2);
                });
            }
            num2=10;
            System.out.println("______________");
        }
    
    
        public void sub1() {
            distributeLock.lock("test");
            num1--;
            distributeLock.unlock("test");
        }
    
    
    
        public void sub2() {
            lock.lock();
            num2--;
            lock.unlock();
        }
    }
    

      redisson框架基于redis实现的分布式锁大量的使用了lua脚本,锁续命使用的TimerTask实现

    3.idea设置不同的端口启动

    上面端口改了启动两次,然后在虚拟机配置一个nginx

    配置负载均衡修改/usr/local/nginx/conf/nginx.conf

    添加

     

     启动nginx

    在/usr/local/nginx/sbin  ./nginx

    4.启动jemeter

     并发测试发现使用分布式锁是ok的,但是jvm的Lock锁进行减操作会减成负数

  • 相关阅读:
    【LOJ #6397】【THUPC2018】—蛋糕 / Cake(DFS)
    【Atcoder Regular Contest 072F】—Dam(单调队列)
    【Atcoder Regular Contest 072F】—Dam(单调队列)
    多测师讲解自动化测试 _RF封装_(三层模式)高级讲师肖sir
    多测师讲解自动化测试 _RF关键字001_( 中)_高级讲师肖sir
    多测师讲解自动化测试 _RF分配id_高级讲师肖sir
    多测师讲解自动化--rf关键字--断言(下)_高级讲师肖sir
    多测师讲解自动化测试 _RF关键字001_(上)_高级讲师肖sir
    多测师讲解自动化测试 _RF模拟鼠标悬停_高级讲师肖sir
    多测师讲解自动化测试 _RF定位iframe框_高级讲师肖sir
  • 原文地址:https://www.cnblogs.com/javashare/p/12757440.html
Copyright © 2011-2022 走看看