zoukankan      html  css  js  c++  java
  • redis 实现分布式锁

    1,分布式锁的应用场景之前在zookeeper 的已经说过了,zookpper 的实现方式如下

    https://www.cnblogs.com/pickKnow/p/11338579.html

    2,基于redis 实现分布式锁

        了解set 和 setnx 命令的不同:

    127.0.0.1:6379> set name 'chris'
    OK
    127.0.0.1:6379> setnx name 'chris'
    (integer) 0
    127.0.0.1:6379> setnx age 20
    (integer) 1
    127.0.0.1:6379> set name 'chris'
    OK
    127.0.0.1:6379> 

        set:往数据库里面插入值,成功,返回ok,key 如果相同,后面的会覆盖前面的

        setnx: 往数据库里面插入值,成功返回1,失败返回0,如果key已经存在,则会插入失败,则会返回0

    expire key timeout:设置有效时长

    name 设置了20秒,过期了key 就不存在了

    127.0.0.1:6379> expire name 20
    (integer) 1
    127.0.0.1:6379> get name
    (nil)
    127.0.0.1:6379> get age
    "20"

    del key: 删除key

    127.0.0.1:6379> del age

    3,基于上面三条命令,可以实现redis分布式锁

        实现思想:在分布式集群环境中,多台JVM 共同去创建key,通过setnx 方式去创建,返回1,代表创建成功,创建成功,则能够获取到锁。

                          给锁设置有效期,根据业务逻辑来设置时长,方式死锁。

                          没有获取到锁的JVM,则一直等待。获取到锁的JVM 实现业务逻辑,逻辑完成,则删除key,将锁释放。

    4,实现脚本如下:

    private static JedisPool pool = null;
        // 设置最大连接数
        private static int maxTotal =200;
        // 设置最大空闲数
        private static int maxIdle = 8;
        // 设置最大等待时间
        private static long maxWaitMillis = 1000*100;
        // 在borrow一个jedis实例时,是否需要验证,若为true,则所有jedis实例均是可用的
        private static boolean testOnBorrow = true;
        // redis ip
        private static String ip = "192.168.178.110";
        // redis 端口
        private static int port = 6379;
        // redis连接timeout
        private static int timeOut = 6000;
        // redis 上锁的key
        private static String redisLockKey = "redisLockKey";
        // redis 上锁的key 豪秒
        private static long redisLockTimeOut = 6000;
    
        static {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(maxTotal);
            config.setMaxIdle(maxIdle);
            config.setMaxWaitMillis(maxWaitMillis);
            config.setTestOnBorrow(testOnBorrow);
            pool = new JedisPool(config, ip, port, timeOut);
        }
    
        @Override
        public boolean lock(String redisLockValue) {
            Jedis resource = null;
            try {
                resource = pool.getResource();
                // 当前时间
                long moment = System.currentTimeMillis();
                // 一把锁的的有效期是 redisLockTimeOut,所以在这个期间内,一直抢key
                // 超过这个时间,说明锁不用抢了,已经过期了,等待下次抢
                while (System.currentTimeMillis() < moment + redisLockTimeOut) {
                    Long setnx = resource.setnx(redisLockKey, redisLockValue);
                    if (setnx == 1) {
                        // 获取到了锁,给锁加上有效期
                        resource.pexpire(redisLockKey, redisLockTimeOut);
                        return true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                resource.close();
            }
            return false;
        }
    
        public void unlock() {
            Jedis resource = null;
            try {
                resource = pool.getResource();
                resource.del(redisLockKey);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                resource.close();
            }
        }
  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/pickKnow/p/11357779.html
Copyright © 2011-2022 走看看