[docs update]redis分布式锁文章图片上传到图床
@ -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/",
|
||||
|
@ -12,7 +12,7 @@ icon: "lock"
|
||||
|
||||
下面是我对本地锁画的一张示意图。
|
||||
|
||||

|
||||

|
||||
|
||||
从图中可以看出,这些线程访问共享资源是互斥的,同一时刻只有一个线程可以获取到本地锁访问共享资源。
|
||||
|
||||
@ -22,7 +22,7 @@ icon: "lock"
|
||||
|
||||
下面是我对分布式锁画的一张示意图。
|
||||
|
||||

|
||||

|
||||
|
||||
从图中可以看出,这些独立的进程中的线程访问共享资源是互斥的,同一时刻只有一个线程可以获取到分布式锁访问共享资源。
|
||||
|
||||
@ -69,7 +69,7 @@ else
|
||||
end
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
这是一种最简易的 Redis 分布式锁实现,实现方式比较简单,性能也很高效。不过,这种方式实现分布式锁存在一些问题。就比如应用程序遇到一些问题比如释放锁的逻辑突然挂掉,可能会导致锁无法被释放,进而造成共享资源无法再被其他线程/进程访问。
|
||||
|
||||
@ -103,7 +103,7 @@ Redisson 是一个开源的 Java 语言 Redis 客户端,提供了很多开箱
|
||||
|
||||
Redisson 中的分布式锁自带自动续期机制,使用起来非常简单,原理也比较简单,其提供了一个专门用来监控和续期锁的 **Watch Dog( 看门狗)**,如果操作共享资源的线程还未执行完成的话,Watch Dog 会不断地延长锁的过期时间,进而保证锁不会因为超时而被释放。
|
||||
|
||||

|
||||

|
||||
|
||||
看门狗名字的由来于 `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)。
|
||||
|
||||

|
||||

|
||||
|
||||
### Redis 如何解决集群情况下分布式锁的可靠性?
|
||||
|
||||
@ -215,11 +215,11 @@ lock.lock(10, TimeUnit.SECONDS);
|
||||
|
||||
Redis 集群下,上面介绍到的分布式锁的实现会存在一些问题。由于 Redis 集群数据同步到各个节点时是异步的,如果在 Redis 主节点获取到锁后,在没有同步到其他节点时,Redis 主节点宕机了,此时新的 Redis 主节点依然可以获取锁,所以多个应用服务就可以同时获取到锁。
|
||||
|
||||

|
||||

|
||||
|
||||
针对这个问题,Redis 之父 antirez 设计了 [Redlock 算法](https://redis.io/topics/distlock) 来解决。
|
||||
|
||||

|
||||

|
||||
|
||||
Redlock 算法的思想是让客户端向 Redis 集群中的多个独立的 Redis 实例依次请求申请加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁,否则加锁失败。
|
||||
|
||||
@ -254,7 +254,7 @@ ZooKeeper 分布式锁是基于 **临时顺序节点** 和 **Watcher(事件监
|
||||
2. 成功获取锁的客户端在出现故障之后,对应的子节点由于是临时顺序节点,也会被自动删除,避免了锁无法被释放。
|
||||
3. 我们前面说的事件监听器其实监听的就是这个子节点删除事件,子节点删除就意味着锁被释放。
|
||||
|
||||

|
||||

|
||||
|
||||
实际项目中,推荐使用 Curator 来实现 ZooKeeper 分布式锁。Curator 是 Netflix 公司开源的一套 ZooKeeper Java 客户端框架,相比于 ZooKeeper 自带的客户端 zookeeper 来说,Curator 的封装更加完善,各种 API 都可以比较方便地使用。
|
||||
|
||||
|
Before Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 42 KiB |
@ -38,6 +38,8 @@ ScopedValue.where(V, <value>)
|
||||
|
||||
作用域值允许在大型程序中的组件之间安全有效地共享数据,而无需求助于方法参数。
|
||||
|
||||
关于作用域值的详细介绍,推荐阅读[作用域值常见问题解答](https://www.happycoders.eu/java/scoped-values/)。
|
||||
|
||||
## JEP 432:记录模式(第二次预览)
|
||||
|
||||
记录模式(Record Patterns) 可对 record 的值进行解构,可以嵌套记录模式和类型模式,实现强大的、声明性的和可组合的数据导航和处理形式。
|
||||
|