1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[docs update]redis分布式锁文章图片上传到图床

This commit is contained in:
Guide 2023-03-28 15:21:32 +08:00
parent ee1ef4a42b
commit d0cbc38d06
11 changed files with 17 additions and 15 deletions

View File

@ -82,13 +82,6 @@ export const sidebarConfig = sidebar({
},
],
},
{
text: "IO",
prefix: "io/",
icon: "code",
children: ["io-basis", "io-design-patterns", "io-model"],
},
{
text: "并发编程",
prefix: "concurrent/",
@ -115,6 +108,13 @@ export const sidebarConfig = sidebar({
},
],
},
{
text: "IO",
prefix: "io/",
icon: "code",
collapsible: true,
children: ["io-basis", "io-design-patterns", "io-model"],
},
{
text: "JVM",
prefix: "jvm/",

View File

@ -12,7 +12,7 @@ icon: "lock"
下面是我对本地锁画的一张示意图。
![本地锁](./images/distributed-lock/jvm-local-lock.png)
![本地锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/jvm-local-lock.png)
从图中可以看出,这些线程访问共享资源是互斥的,同一时刻只有一个线程可以获取到本地锁访问共享资源。
@ -22,7 +22,7 @@ icon: "lock"
下面是我对分布式锁画的一张示意图。
![分布式锁](./images/distributed-lock/distributed-lock.png)
![分布式锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock.png)
从图中可以看出,这些独立的进程中的线程访问共享资源是互斥的,同一时刻只有一个线程可以获取到分布式锁访问共享资源。
@ -69,7 +69,7 @@ else
end
```
![Redis 实现简易分布式锁](./images/distributed-lock/distributed-lock-setnx.png)
![Redis 实现简易分布式锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-setnx.png)
这是一种最简易的 Redis 分布式锁实现,实现方式比较简单,性能也很高效。不过,这种方式实现分布式锁存在一些问题。就比如应用程序遇到一些问题比如释放锁的逻辑突然挂掉,可能会导致锁无法被释放,进而造成共享资源无法再被其他线程/进程访问。
@ -103,7 +103,7 @@ Redisson 是一个开源的 Java 语言 Redis 客户端,提供了很多开箱
Redisson 中的分布式锁自带自动续期机制,使用起来非常简单,原理也比较简单,其提供了一个专门用来监控和续期锁的 **Watch Dog 看门狗)**如果操作共享资源的线程还未执行完成的话Watch Dog 会不断地延长锁的过期时间,进而保证锁不会因为超时而被释放。
![Redisson 看门狗自动续期](./images/distributed-lock/distributed-lock-redisson-renew-expiration.png)
![Redisson 看门狗自动续期](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-redisson-renew-expiration.png)
看门狗名字的由来于 `getLockWatchdogTimeout()` 方法,这个方法返回的是看门狗给锁续期的过期时间,默认为 30 秒([redisson-3.17.6](https://github.com/redisson/redisson/releases/tag/redisson-3.17.6))。
@ -207,7 +207,7 @@ lock.lock(10, TimeUnit.SECONDS);
实际项目中,我们不需要自己手动实现,推荐使用我们上面提到的 **Redisson** 其内置了多种类型的锁比如可重入锁Reentrant Lock、自旋锁Spin Lock、公平锁Fair Lock、多重锁MultiLock、 红锁RedLock、 读写锁ReadWriteLock
![](./images/distributed-lock/redisson-readme-locks.png)
![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/redisson-readme-locks.png)
### Redis 如何解决集群情况下分布式锁的可靠性?
@ -215,11 +215,11 @@ lock.lock(10, TimeUnit.SECONDS);
Redis 集群下,上面介绍到的分布式锁的实现会存在一些问题。由于 Redis 集群数据同步到各个节点时是异步的,如果在 Redis 主节点获取到锁后在没有同步到其他节点时Redis 主节点宕机了,此时新的 Redis 主节点依然可以获取锁,所以多个应用服务就可以同时获取到锁。
![](./images/distributed-lock/redis-master-slave-distributed-lock.png)
![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/redis-master-slave-distributed-lock.png)
针对这个问题Redis 之父 antirez 设计了 [Redlock 算法](https://redis.io/topics/distlock) 来解决。
![](./images/distributed-lock/distributed-lock-redis.io-realock.png)
![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-redis.io-realock.png)
Redlock 算法的思想是让客户端向 Redis 集群中的多个独立的 Redis 实例依次请求申请加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁,否则加锁失败。
@ -254,7 +254,7 @@ ZooKeeper 分布式锁是基于 **临时顺序节点** 和 **Watcher事件监
2. 成功获取锁的客户端在出现故障之后,对应的子节点由于是临时顺序节点,也会被自动删除,避免了锁无法被释放。
3. 我们前面说的事件监听器其实监听的就是这个子节点删除事件,子节点删除就意味着锁被释放。
![](./images/distributed-lock/distributed-lock-zookeeper.png)
![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-zookeeper.png)
实际项目中,推荐使用 Curator 来实现 ZooKeeper 分布式锁。Curator 是 Netflix 公司开源的一套 ZooKeeper Java 客户端框架,相比于 ZooKeeper 自带的客户端 zookeeper 来说Curator 的封装更加完善,各种 API 都可以比较方便地使用。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View File

@ -38,6 +38,8 @@ ScopedValue.where(V, <value>)
作用域值允许在大型程序中的组件之间安全有效地共享数据,而无需求助于方法参数。
关于作用域值的详细介绍,推荐阅读[作用域值常见问题解答](https://www.happycoders.eu/java/scoped-values/)。
## JEP 432记录模式第二次预览
记录模式Record Patterns 可对 record 的值进行解构,可以嵌套记录模式和类型模式,实现强大的、声明性的和可组合的数据导航和处理形式。