- 说明
在微服务的项目中,我们经常会遇到多个服务对统一资源的并发访问,比如文件资源、数据库资源、以及缓存资源等。如果我们不对这些资源做访问同步控制,那么将会对我们的数据的唯一性造成影响。要做资源的同步不仅仅只是线程同步这么简单,该同步是对服务级别的同步。
- 同步设计
- 基础同步
第一种方式,系统考虑最基础的同步,采用redis作为中间件,没有等待唤醒机制,同步服务采用轮询的方式去获取分布式锁。所有服务访问需要同步的资源的时候,首先去获取锁,如果获取到锁那么就加锁,然后访问资源,访问完成之后再释放锁。如果没有获取到锁,那么就线程自动睡眠1秒钟,然后继续轮询获取锁。这样是最简单的办法,但是这样对系统的性能可能会造成影响。
如下流程图方式:
- 等待唤醒机制
第二种方式,系统考虑的是等待与唤醒机制,当服务需要访问临界资源的时候,首先去获取分布式锁,如果分布式锁被占用,那么他将服务阻塞,如果锁被释放掉,那么将唤醒该锁上所有等待的服务。这样做的好处是可以提高系统性能。
如下流程图所示:
- 应用架构
框架采用的springboot
- 使用方式
此分布式锁是在springboot的2.0.6release版本上面进行开发的。
- 引入包
在maven中引入dlock的包:
<dependency>
<groupId>com.moon</groupId>
<artifactId>dlock</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
引入该包之后,可能还需要引入该包锁依赖的包。
- 配置
需要在application.yml文件中加入如下配置:
- 代码使用
- 注解方式
在需要分布式同步的方法上面加上ServerSync注解即可同步。ServerSync的方式有两个,第一个是锁的同步模式,分为block(阻塞)、polling(轮询)。阻塞表示加了锁之后,当前服务自动阻塞,等待其他服务用完锁之后进行唤醒;轮询的方式表示该锁不阻塞,会一直轮询获取锁,直到超时。
- 轮询锁:
如图所示,轮询锁:
效果如下:
- 阻塞锁
如下图所示,阻塞锁的使用:
调用效果如下:
- 同步代码块
效果如下: