红锁实现
多个Redisson + 过半加锁成功

这几台redis都是主,没有存,这样就不需要进行数据同步操作,所以没问题
红锁的流程
- 首先获取当前时间
- 按照一定的顺序给 n 台独立的redis 进行加锁
- 一切顺利的情况是给这几个redis 一直加锁完成
- 如果有一部分redis没有加锁完成,就要计算加锁完成的数量是否已过半
- 加锁失败的情况:a、加锁时间 > 锁的有效期 b、未过半
- 所有的redis 都要释放一遍锁
红锁常见问题
服务器时间校准问题——需要运维维护
启动挂掉的redis时要延时启动
锁的过期时间是20s、启动挂掉的redis 30s后再启动
场景:线程一在加锁的时候,给redis 1、2、3 都加锁,过半过去锁成功,然后redis 3 挂掉,这时候 线程一还没有执行完逻辑。然后运维人员启动了这个redis、这个时候线程二进来 会给redis 3、4、5 上锁成功,同样能获取到锁。 这样两个线程在同一段时间就都能拿到锁,违背了锁的互斥性。
怎么解决? —- 运维人员延迟启动、延时启动redis 的时间一定要大于锁的过期时间。

实现
配置的n个Redis 是独立的n台Redis n 是奇数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class RedisRedissonRedLockLock {
@Autowired @Qualifier("redissonRed1") private RedissonClient redissonRed1; @Autowired @Qualifier("redissonRed2") private RedissonClient redissonRed2; @Autowired @Qualifier("redissonRed3") private RedissonClient redissonRed3; @Autowired OrderService orderService;
@Override public String test(){ String lockKey = "lockKey"; RLock rLock1 = redissonRed1.getLock(lockKey); RLock rLock2 = redissonRed2.getLock(lockKey); RLock rLock3 = redissonRed3.getLock(lockKey); RedissonRedLock rLock = new RedissonRedLock(rLock1,rLock2,rLock3);
try { rLock.lock(); try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } finally { rLock.unlock(); } return null; } }
|