• redis实现分布式锁


    1.锁的处理

    • 单应用中(单进程多线程情况)锁的处理:
      • synchronized
      • lock
    • 分布式应用中锁的处理:
      • 数据库乐观锁;
      • 基于zookeeper的分布式锁;
      • 基于redis的分布式锁

    2.分布式锁需要注意事项

    • 互斥性: 在任意时刻,只有一个客户端能持有锁
    • 同一性:   加锁和解锁必须是同一个客户端,客户端自己不能把别的客户端加的锁给解了
    • 避免死锁:  即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁 

    3.获取锁

    方式一:使用set命令实现

     代码如下:

    /**
         * 使用redis的set命令实现获取分布式锁
         * @param lockKey       可以就是锁
         * @param requestId        请求ID,保证同一性
         * @param expireTime    过期时间,避免死锁
         * @return
         */
        public static boolean getLock(String lockKey,String requestId,int expireTime) {
            //NX:保证互斥性
            String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);
            if("OK".equals(result)) {
                return true;
            }
            
            return false;
        }
    方式二:使用setnx命令,这里使用synchronized保证方法的原子性
    1 public static synchronized boolean Lock2(String lockKey,String requestId,int expireTime) {
    2         Long result = jedis.setnx(lockKey, requestId);
    3         if(result == 1) {
    4             jedis.expire(lockKey, expireTime);
    5             return true;
    6         }
    7 
    8         return false;
    9     }

    4.释放锁

    方式一:使用del命令

        /**
         * 释放分布式锁
         * @param lockKey
         * @param requestId
         */
        public static void releaseLock(String lockKey,String requestId) {
            if (requestId.equals(jedis.get(lockKey))) {
                jedis.del(lockKey);
            }
        }

    方式二:使用Lua脚本

    public static boolean releaseLock(String lockKey, String requestId) {
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
    
            if (result.equals(1L)) {
                return true;
            }
            return false;
        }
  • 相关阅读:
    (三)mybatis 的使用(入门)
    (二)mybatis框架原理(图解)
    (一)使用 mybatis 的缘由
    (八)Spring 事务管理
    (七)Spring 配置 c3p0 连接池
    (六)Spring 中的 JdbcTemplate
    熔断监控集群(Turbine)
    熔断监控面板(Hystrix Dashboard)
    容错机制和熔断(Hystrix)
    服务消费和负载(Feign)
  • 原文地址:https://www.cnblogs.com/kiwi-deng/p/11608874.html
Copyright © 2020-2023  润新知