SpringBoot项目上高并发问题的解决方案

简介:大家好,我是程序员枫哥,🌟一线互联网的IT民工、📝资深面试官、🌹Java跳槽网创始人。拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队,目前业余时间专注Java技术分享,春招/秋招/社招/跳槽,一对一学习辅助,项目接活开发。
🌈更多学习内容, 欢迎👏关注👀【文末】微信公众号:IT枫斗者
🌟🌟程序员找工作,就上Java跳槽网:www.javatiaocao.com

SpringBoot项目上高并发问题的解决方案

单机模式下高并发问题

  • 拿以前springboot整合布隆过滤网篇的一个接口直接做改造:假设编号为2的苹果库存还有一个,现在有个接口去买这个苹果并生成订单号以便于后期支付,得到如下:

  • 数据表:

  • 在这里插入图片描述

  • 接口

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 通过jmeter模拟一秒钟有100个用户购买这个苹果,结果会是什么?

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 会发现直接卖爆了,一个苹果被卖了几十单。怎么解决这个并发问题呢?

乐观锁

  • CAS先比较再交换,Java中提供了Atomic开头的类,例如AtomicInteger、AtomicLong、AtomicReference等原子类都是此思想来支持CAS操作的。进行如下改造,来实现先比较在修改值的方式解决该问题。其实就是在把cas想做是一个原子操作。改造方式就是例如给商品表增加一个字段用来表示该次原子性操作时,他应该是什么值,若是则修改,不然就不修改。如下:

  • 在这里插入图片描述

  • 增加一个number字段,原理就是每次修改时带上这个number条件,而每次减少count后修改number的值(原子性)第一个请求的用户这样处理,其他同时查到这个订单的其他用户,在减少count时根据number条件却查不到这个订单了从而无法再生成订单。代码如下:

  • 在这里插入图片描述

  • 继续jmeter测试,再看看结果如何?

  • 在这里插入图片描述

  • 发现通过这种方式的确实现了防止超卖的现象。

  • 优点:不用加锁,不会阻塞其他线程,性能相比较好。缺点:需要增加

  • 字段,并且由于是在数据库层面保持原子性可能导致多事务操作操作同一数据时导致冲突,引起数据一致性问题。

  • 结论:所以在并发较少的情况下可以使用乐观锁方式。

悲观锁

synchronized锁
  • 改造代码如下:

  • 在这里插入图片描述

  • 通过测试得出:

  • 在这里插入图片描述

  • 发现实现了防止超卖,但是synchronized锁是基于jvm层面的,因此并不适用于集群模式。集群模式会涉及到一个服务的多实例,就会有多个jvm,synchronized只能保证当前实例在当前jvm下的原子性操作。

  • 我们用idea模拟一个集群来进行测试,如下:

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 执行一下jmeter,看看结果是什么?

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 在这里插入图片描述

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 我们可以看到模拟的每一个机器都抢到了一个,那依旧完犊子了呀。

  • 结论:集群模式下synchronized不可取。

Lock锁
  • 相比synchronized而言,这个锁是方法,而synchronized是关键字。使用lock的实现ReentrantLock

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 改造代码如下:

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 继续在模拟集群下进行测试,结果如下:

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 结果和synchronized效果一样,只有在单机模式下可以保证没问题,而集群模式下依然会出现问题。

  • 结论:集群模式下Lock锁不可取。

集群模式下高并发问题

  • 上面讲了单机模式下可以采用的方式解决并发问题,但是有些方式在集群模式下就不可用了,下面就试一下在集群模式下依旧可以解决并发问题的方法。

  • 还是先看看不做任何处理的集群下进行抢商品是什么情况?

  • img

  • img

  • img

  • 简直是炸裂,这样上线不被领导怼着鼻子。

  • 那我们怎么改造呢?我们引入Redisson。

  • 我们直接使用前面整合布隆过滤网的demo,就不讲整合Redisson了,已经讲过了,直接这里使用。

  • 改造后的代码如下:

  • 在这里插入图片描述

  • jmeter执行后的结果如下:

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 三台机器只有一台抢到了一个苹果,达到了目的。Redisson的这个分布式锁的使用也很简单,如果服务挂掉,无法执行final的代码会如何,如下看看:

  • 在这里插入图片描述

  • 我们打个断点假设服务在获取锁后服务挂了,redis如下:

  • 在这里插入图片描述

  • 可10秒后,如下:

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 锁已经过期失效不见了。因此并不会导致死锁的发生,这个分布式锁的具体实现大佬们可以评论区交流谈论或者后面再继续说。

  • 26
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT枫斗者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值