目录
- 2.9 RedLock
- 2.9.1 上述实现的分布式锁在集群状态下失效的原因
- 2.9.2 解决方式-RedLock
- 2.10 ==redisson中的分布式锁==
- 简单使用redisson中的锁
- Redisson常用配置
- 2.10.1 Redisson可重入锁实现原理
- 2.10.2 公平锁(Fair Lock)
2.9 RedLock
2.9.1 上述实现的分布式锁在集群状态下失效的原因
redis集群状态下的问题:
- 客户端A从master获取到锁
- 在master将锁同步到slave之前,master宕掉了。
- slave节点被晋级为master节点
- 客户端B取得了同一个资源被客户端A已经获取到的另外一个锁。
2.9.2 解决方式-RedLock
解决集群下锁失效,参照redis官方网站针对redlock文档:https://redis.io/topics/distlock
加锁算法
2.10 redisson中的分布式锁
Redisson提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)
Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
官方文档地址:https://github.com/redisson/redisson/wiki
简单使用redisson中的锁
注入 RedissonClient 客户端
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
// 默认连接地址 127.0.0.1:6379
Config config = new Config();
config.useSingleServer().setAddress("redis://121.40.182.123:6379").setPassword("houchen");
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
使用 RedisClient的锁。StockService 代码片段如下
public void deduct() {
RLock lock = redissonClient.getLock("lock");
lock.lock();
try {
String stockStr = redisTemplate.opsForValue().get("stock:" + "1001");
// 2. 判断库存是否充足
if (stockStr != null && stockStr.length() != 0) {
Long stock = Long.parseLong(stockStr);
if (stock > 0) {
redisTemplate.opsForValue().set("stock:" + "1001", String.valueOf(stock - 1));
}
}
} finally {
lock.unlock();
}
}
使用 Jmeter并发压测后,查看redis的库存确实减为0,表明redisson锁是确实是可用的