ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分布式分段锁 解决高并发情况锁导致请求处理慢的问题

2022-02-24 19:59:24  阅读:157  来源: 互联网

标签:count return String stockCount lock 并发 result 分布式 分段


使用redisson 分布式锁 会导致 线程并行执行,在秒杀系统中导致并发下降,此时可以对库存进行分段 如 stockCount = 40 分成四十段,分段的段数和总库存 相关, 用户请求时,随机分配一个段,若获取失败再重试几次,以保证尽可能购买到,详细代码如下
book 不使用锁 本机测试 20000/分钟
bookWithLock:使用分布式锁 但是没有分段 测试结果 1000/分钟
bookWithLock2 使用分布式锁 分段20时测试结果12000/分钟 分段40时测试结果 16000/分钟


  1. @Slf4j
  2. @Service
  3. public class OrderServiceImpl implements OrderService {
  4. private static String key = "count";
  5. private static int stockCount = 40;
  6. @Autowired
  7. private RedissonClient redissonClient;
  8. @Autowired
  9. private StringRedisTemplate stringRedisTemplate;
  10. @Override
  11. public String book() {
  12. return this.decrementOrder();
  13. }
  14. @Override
  15. public String bookWithLock() {
  16. RLock lock = this.redissonClient.getLock("lock");
  17. Boolean result = false;
  18. try {
  19. result = lock.tryLock(10, TimeUnit.SECONDS);
  20. if (result) {
  21. return this.decrementOrder();
  22. } else {
  23. log.info("==================获取锁失败================");
  24. }
  25. // Boolean result = lock.tryLock(10, TimeUnit.SECONDS);
  26. // if (result) {
  27. // return this.decrementOrder();
  28. // } else {
  29. // log.info("获取锁失败");
  30. // return "获取锁失败";
  31. // }
  32. } catch (Exception e) {
  33. log.error(e.getMessage());
  34. return "预定失败";
  35. } finally {
  36. if (result) {
  37. lock.unlock();
  38. }
  39. }
  40. return "0";
  41. }
  42. private String decrementOrder() {
  43. Long count = Long.valueOf(this.stringRedisTemplate.opsForValue().get(key));
  44. if (count > 0) {
  45. count = this.stringRedisTemplate.opsForValue().decrement(key);
  46. log.info("==================库存还剩{}个================", count);
  47. return String.valueOf(count);
  48. } else {
  49. log.info("库存不足");
  50. }
  51. return "库存不足";
  52. }
  53. @Override
  54. public Long initCount(Long count) {
  55. count = count == null ? 100000 : count;
  56. if (count < stockCount) {
  57. stockCount = 1;
  58. this.stringRedisTemplate.opsForValue().set(key + "_0", count.toString());
  59. } else {
  60. for (int i = 0; i < stockCount; i++) {
  61. this.stringRedisTemplate.opsForValue().set(key + "_" + i, String.valueOf(count / stockCount));
  62. }
  63. if (count % stockCount != 0) {
  64. this.stringRedisTemplate.opsForValue().set(key + "_" + 0, String.valueOf(count / stockCount + count % stockCount));
  65. }
  66. }
  67. this.stringRedisTemplate.opsForValue().set(key, count.toString());
  68. return Long.valueOf(this.stringRedisTemplate.opsForValue().get(key));
  69. }
  70. @Override
  71. public String bookWithLock2() {
  72. RLock lock = null;
  73. Boolean result = false;
  74. //尝试三次
  75. for (int i = 0; i < 3; i++) {
  76. try {
  77. int index = getRandom(stockCount);
  78. lock = this.redissonClient.getLock("lock" + index);
  79. result = lock.tryLock(10, TimeUnit.SECONDS);
  80. if (result) {
  81. String count = decrementOrder2(index);
  82. //如果没获取到(某个段的库存不足)则释放锁
  83. if ("-1".equals(count)) {
  84. lock.unlock();
  85. } else {
  86. return count;
  87. }
  88. }
  89. } catch (Exception ex) {
  90. log.error("执行失败", ex);
  91. } finally {
  92. if (result && lock != null) {
  93. try {
  94. lock.unlock();
  95. } catch (IllegalMonitorStateException e) {
  96. }
  97. }
  98. }
  99. }
  100. log.info("预定失败");
  101. return "0";
  102. }
  103. private String decrementOrder2(Integer index) {
  104. index = index == null ? 0 : index;
  105. //尝试获取次数
  106. String keyTemp = key + "_" + index;
  107. Long count = Long.valueOf(this.stringRedisTemplate.opsForValue().get(keyTemp));
  108. if (count > 0) {
  109. count = this.stringRedisTemplate.opsForValue().decrement(keyTemp);
  110. log.info("==================库存还剩{}个================", count);
  111. return String.valueOf(count);
  112. }
  113. log.info("获取是失败.......");
  114. return "-1";
  115. }
  116. private int getRandom(int count) {
  117. return new Random().nextInt(count);
  118. }
  119. }

标签:count,return,String,stockCount,lock,并发,result,分布式,分段
来源: https://blog.csdn.net/qq_17056391/article/details/123119522

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有