⚡️功能描述:使用springboot框架开发的高并发抢购秒杀系统
IDE:IntelliJ IDEA
数据库:Datagrip
+ Mysql
版本控制: Git
压测工具: jmeter
包管理:Maven
Springboot
Guava
Shiro
Jwt
MybatisPlus
Hikari连接池
Redis
RabbitMQ
使用Java Web Token 作为登录验证方式,实现高并发秒杀系统,用户在sso系统中登录后请求只需带Token,分布式系统中的每个系统都可以对用户进行身份验证.
使用理由:
-
用户请求带token各个系统都可以进行验证身份
-
token中带有用户的有效身份信息,可以通过解密token快速获取到用户的主要信息,不用再去数据库中加载.
-
可解决分布式系统中登录后session共享问题
Ps:本项目集成SSO系统,可以从本项目中分离出登录的逻辑,只留下验证的逻辑即可
RateLimiter是guava提供的基于令牌桶算法的限流实现类,通过调整生成token的速率来限制用户频繁访问秒杀页面,从而达到防止超大流量冲垮系统。(令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务)
PS:分布式秒杀系统可使用redis+lua替代RateLimiter进行统一的限流
在项目中使用本地内存标记多个商品的布尔值,每次一个商品抢购根据这个布尔值进行判断,如果商品抢购完毕,标记为true后,后续抢购这个商品请求直接拒绝.
使用理由:
- 减少请求对redis中的库存进行访问的次数,减小redis的压力
抢购开始前,将商品和库存数据同步到redis中,抢购操作在redis中进行处理,通过Redis预减少库存减少数据库访问 使用理由:
- 减小Mysql的压力
使用RabbitMQ用异步队列处理下单,实际做了一层缓冲保护,做了一个窗口模型,窗口模型会实时的刷新用户秒杀的状态 使用理由
- 保护系统不受高流量的冲击而导致系统崩溃的问题,将接口解耦
Ps:异步下单后,前端需要读秒请求,不要使用轮询请求,减小接口压力
- 对库存更新时,先对库存判断,只有当库存大于0才能更新库存
- 对用户id和商品id建立一个唯一索引,通过这种约束避免同一用户发同时两个请求秒杀到两件相同商品
- 实现乐观锁,给商品信息表增加一个version字段,为每一条数据加上版本。每次更新的时候version+1,并且更新时候带上版本号,当提交前版本号等于更新前版本号,说明此时没有被其他线程影响到,正常更新,如果冲突了则不会进行提交更新。当库存是足够的情况下发生乐观锁冲突就进行一定次数的重试。