【三十】springboot项目上高并发解决示例

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 【三十】springboot项目上高并发解决示例


       本章演示在springboot项目中的高并发demo,演示导致的问题,以及单机部署下的解决方案和集群部署下的解决方式以及分布式下的解决方案。

一、单机模式下高并发问题

       前提:先写一个减扣数据库产品数量的一个接口作为测试。

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

1、数据表:

2、接口

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

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

PS:java提供了锁来处理

1、乐观锁

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

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

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

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

  • 优点:不用加锁,不会阻塞其他线程,性能相比较好。
  • 缺点:需要增加表字段,并且由于是在数据库层面保持原子性可能导致多事务操作操作同一数据时导致冲突,引起数据一致性问题。

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

2、悲观锁

       将通过下面两种锁来进行演示。

2.1、synchronized锁

       改造代码如下:

       通过测试得出:

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

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

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

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

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

2.2、Lock锁

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

       改造代码如下:

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

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

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

二、集群模式下高并发问题

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

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

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

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

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

       改造后的代码如下:

       jmeter执行后的结果如下:

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

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

       可10秒后,如下:

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

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
19天前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
99 0
|
6月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
4天前
|
安全 Java 编译器
springboot 整合表达式计算引擎 Aviator 使用示例详解
本文详细介绍了Google Aviator 这款高性能、轻量级的 Java 表达式求值引擎
|
2月前
|
Java 应用服务中间件 API
Vertx高并发理论原理以及对比SpringBoot
Vertx 是一个基于 Netty 的响应式工具包,不同于传统框架如 Spring,它的侵入性较小,甚至可在 Spring Boot 中使用。响应式编程(Reactive Programming)基于事件模式,通过事件流触发任务执行,其核心在于事件流 Stream。相比多线程异步,响应式编程能以更少线程完成更多任务,减少内存消耗与上下文切换开销,提高 CPU 利用率。Vertx 适用于高并发系统,如 IM 系统、高性能中间件及需要较少服务器支持大规模 WEB 应用的场景。随着 JDK 21 引入协程,未来 Tomcat 也将优化支持更高并发,降低响应式框架的必要性。
Vertx高并发理论原理以及对比SpringBoot
|
5月前
|
Java 数据安全/隐私保护 网络架构
一个简单的示例在spring boot中实现国际化
一个简单的示例在spring boot中实现国际化
|
24天前
|
前端开发 Java 关系型数据库
【保姆级SSM教程】高并发朋友圈点赞项目设计
【保姆级SSM教程】高并发朋友圈点赞项目设计
25 0
|
3月前
|
Java
SpringBoot 接口并发限制(Semaphore)
SpringBoot 接口并发限制(Semaphore)
71 1
|
3月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
55 5
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的高并发慕课网的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的高并发慕课网的详细设计和实现(源码+lw+部署文档+讲解等)
|
5月前
|
缓存 NoSQL Java
Spring Boot中的高并发处理
Spring Boot中的高并发处理