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.7 kB

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