redis是我们在工作中最常接触到的中间件,这个中间件的作用最经常用来做缓存、缓存数据库等功能。redis也是可以实现分布式锁的,我们可以通过redis+lua脚本的方式来实现加锁和释放锁的操作。下面来看实现方式:
/*** redisTemplate 加锁* @param key* @return*/public boolean setNxLock(String lockKey, String value, int expireTime){boolean ret = false;try{String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end";RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);// Object result = redisTemplate.execute(redisScript, (List<String>) new StringRedisSerializer(), Collections.singletonList(lockKey),value,expireTime + "");Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey),value,expireTime + "");System.out.println(result + "-----------");if(SUCCESS.equals(result)) {return true;}}catch(Exception e){e.printStackTrace();}return ret;}/*** 释放锁* @param lockKey* @param value* @return*/public boolean releaseLock(String lockKey, String value){String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey),value);if(SUCCESS.equals(result)) {return true;}return false;}
我们可以采用redisson客户端工具来实现分布锁,

redission客户端工具通过可重入锁的方式来实现锁,并且在redisson实例存活时,会根据Config.lockWatchdogTimeout来实时检查是否运行完毕,当未运行完毕时,就会延长时间。而如果redisson实例宕机之后,过了加锁时间就会自动解开。而当其他客户端对同一个资源进行加锁时,如果仍未解锁,则会返回剩余时间,然后通过while循环不断尝试加锁。
redisson客户端工具的实现原理:

这种情况小编想到的是可以通过哨兵模式来搭建主从,同时开始aof持久化的方式,配置好写入aof日志内容的时机。redis发生宕机的可能性还是比较小的,所以一般采用第一种方式就可以,第二种可以结合具体情况来处理。
文章转载自Lord Lean Notes,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




