You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. ## spring-boot-demo-distributed-lock-redisson
  2. > 此 demo 主要演示了 Spring Boot 如何基于 Redisson 实现一个分布式锁
  3. ## 1.开发步骤
  4. 在 `demo-distributed-lock-api` 模块中,已经实现了基于 AOP 的分布式锁注解拦截、简单的扣减库存案例,因此本模块只需要实现以下两个接口即可。
  5. - `com.xkcoding.distributed.lock.api.DistributedLock`
  6. - `com.xkcoding.distributed.lock.api.DistributedLockClient`
  7. ### 1.1.添加依赖
  8. ```xml
  9. <dependencies>
  10. <dependency>
  11. <groupId>com.xkcoding</groupId>
  12. <artifactId>demo-distributed-lock-api</artifactId>
  13. <version>1.0.0-SNAPSHOT</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.redisson</groupId>
  17. <artifactId>redisson</artifactId>
  18. <version>${redisson.version}</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.projectlombok</groupId>
  22. <artifactId>lombok</artifactId>
  23. <optional>true</optional>
  24. </dependency>
  25. </dependencies>
  26. ```
  27. ### 1.2.代码实现
  28. #### 1.2.1.RedissonDistributedLock
  29. > 基于 Redisson 实现分布式锁
  30. ```java
  31. public class RedissonDistributedLock extends DistributedLock {
  32. private final RedissonClient redissonClient;
  33. protected RedissonDistributedLock(RedissonClient redissonClient, String lockKey, long lockTime, TimeUnit timeUnit) {
  34. super(lockKey, lockTime, timeUnit);
  35. this.redissonClient = redissonClient;
  36. }
  37. @Override
  38. public void lock() {
  39. redissonClient.getLock(lockKey).lock();
  40. }
  41. @Override
  42. public boolean tryLock() {
  43. try {
  44. return tryLock(lockTime, timeUnit);
  45. } catch (InterruptedException e) {
  46. return false;
  47. }
  48. }
  49. @Override
  50. public boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException {
  51. return redissonClient.getLock(lockKey).tryLock(lockTime, timeUnit);
  52. }
  53. @Override
  54. public void unlock() {
  55. redissonClient.getLock(lockKey).unlock();
  56. }
  57. }
  58. ```
  59. #### 1.2.2.RedissonDistributedLockClient
  60. > 获取一把 Redisson 分布式锁
  61. ```java
  62. @RequiredArgsConstructor
  63. public class RedissonDistributedLockClient implements DistributedLockClient {
  64. private final RedissonClient redissonClient;
  65. /**
  66. * 获取一把锁
  67. *
  68. * @param lockKey 锁的标识
  69. * @param lockTime 锁的时间
  70. * @param timeUnit 锁的时间单位
  71. * @return 锁
  72. */
  73. @Override
  74. public DistributedLock getLock(String lockKey, long lockTime, TimeUnit timeUnit) {
  75. return new RedissonDistributedLock(redissonClient, lockKey, lockTime, timeUnit);
  76. }
  77. }
  78. ```
  79. #### 1.2.3.自动装配
  80. > 替换 `demo-distributed-lock-api` 中的默认实现
  81. ```java
  82. @Configuration(proxyBeanMethods = false)
  83. public class RedissonDistributedLockAutoConfiguration {
  84. @Bean
  85. public RedissonClient redissonClient() {
  86. Config config = new Config();
  87. config.useSingleServer().setAddress("redis://127.0.0.1:6379");
  88. return Redisson.create(config);
  89. }
  90. @Bean
  91. public RedissonDistributedLockClient distributedLockClient(RedissonClient redissonClient) {
  92. return new RedissonDistributedLockClient(redissonClient);
  93. }
  94. }
  95. ```
  96. ## 2.测试
  97. ### 2.1.环境搭建
  98. 主要是 mysql 及 redis 环境的搭建,这里我提供了 docker-compose 文件,方便同学们一键启动测试环境
  99. ```bash
  100. $ cd demo-distributed-lock/demo-distributed-lock-redisson
  101. $ docker compose -f docker-compose.env.yml up
  102. ```
  103. ### 2.2.测试流程
  104. 这里我通过 Apache Bench 进行模拟并发场景,我也构建了一个压测镜像 `xkcoding/ab:alpine-3.16.2` ,方便同学们进行快速测试
  105. > 注意:每次启动项目,都会在重置库存,你也可以手动调用 `/demo/stock/reset` 接口重置
  106. #### 2.2.1.测试无分布式锁下高并发请求是否会发生超卖
  107. 1. 把 `RedissonDistributedLockAutoConfiguration` 类全部注释掉,这将不会装配 Redisson 分布式锁
  108. 2. 启动 `RedissonDistributedLockApplication`
  109. 3. 模拟 5000 请求数 100 并发的压测环境 `docker run -it --rm xkcoding/ab:alpine-3.16.2 ab -n 5000 -c 100 http://${替换成你电脑的内网IP}:8080/demo/stock/reduce`
  110. 4. 等待压测结束,前往数据库查看库存是否从 5000 减为 0
  111. #### 2.2.2.测试 Redisson 分布式锁
  112. 1. 把 `RedissonDistributedLockAutoConfiguration` 类的注释解开,此时 Spring Boot 会自动装配我们的 Redisson 分布式锁
  113. 2. 再次启动 `RedissonDistributedLockApplication`
  114. 3. 再次模拟 5000 请求数 100 并发的压测环境 `docker run -it --rm xkcoding/ab:alpine-3.16.2 ab -n 5000 -c 100 http://${替换成你电脑的内网IP}:8080/demo/stock/reduce`
  115. 4. 等待压测结束,前往数据库查看库存是否从 5000 减为 0
  116. ## 3.参考
  117. - [Redisson](https://github.com/redisson/redisson/wiki)