# 如何设计一个秒杀系统
## 系统的特点
- 高性能:秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键
- 一致性:秒杀商品减库存的实现方式同样关键,有限数量的商品在同一时刻被很多倍的请求同时来减库存,在大并发更新的过程中都要保证数据的准确性。
- 高可用:秒杀时会在一瞬间涌入大量的流量,为了避免系统宕机,保证高可用,需要做好流量限制
## 优化思路
- 后端优化:将请求尽量拦截在系统上游
- 限流:屏蔽掉无用的流量,允许少部分流量走后端。假设现在库存为 10,有 1000 个购买请求,最终只有 10 个可以成功,99% 的请求都是无效请求
- 削峰:秒杀请求在时间上高度集中于某一个时间点,瞬时流量容易压垮系统,因此需要对流量进行削峰处理,缓冲瞬时流量,尽量让服务器对资源进行平缓处理
- 异步:将同步请求转换为异步请求,来提高并发量,本质也是削峰处理
- 利用缓存:创建订单时,每次都需要先查询判断库存,只有少部分成功的请求才会创建订单,因此可以将商品信息放在缓存中,减少数据库查询
- 负载均衡:利用 Nginx 等使用多个服务器并发处理请求,减少单个服务器压力
- 前端优化:
- 限流:前端答题或验证码,来分散用户的请求
- 禁止重复提交:限定每个用户发起一次秒杀后,需等待才可以发起另一次请求,从而减少用户的重复请求
- 本地标记:用户成功秒杀到商品后,将提交按钮置灰,禁止用户再次提交请求
- 动静分离:将前端静态数据直接缓存到离用户最近的地方,比如用户浏览器、CDN 或者服务端的缓存中
- 防作弊优化:
- 隐藏秒杀接口:如果秒杀地址直接暴露,在秒杀开始前可能会被恶意用户来刷接口,因此需要在没到秒杀开始时间不能获取秒杀接口,只有秒杀开始了,才返回秒杀地址 url 和验证 MD5,用户拿到这两个数据才可以进行秒杀
- 同一个账号多次发出请求:在前端优化的禁止重复提交可以进行优化;也可以使用 Redis 标志位,每个用户的所有请求都尝试在 Redis 中插入一个 `userId_secondsKill` 标志位,成功插入的才可以执行后续的秒杀逻辑,其他被过滤掉,执行完秒杀逻辑后,删除标志位
- 多个账号一次性发出多个请求:一般这种请求都来自同一个 IP 地址,可以检测 IP 的请求频率,如果过于频繁则弹出一个验证码
- 多个账号不同 IP 发起不同请求:这种一般都是僵尸账号,检测账号的活跃度或者等级等信息,来进行限制。比如微博抽奖,用 iphone 的年轻女性用户中奖几率更大。通过用户画像限制僵尸号无法参与秒杀或秒杀不能成功
## 代码优化
代码整体思路参考的 [@crossoverJie](<https://github.com/crossoverJie>),做了以下几点变动
1. 将 SSM 换成 SpringBoot,开箱即用,替换 Mapper XML 为注解,去掉 Dubbo 和 Zookeeper
2. 原项目中依赖了开发者自己的开源包 [distributed-redis-tool](<https://github.com/crossoverJie/distributed-redis-tool>),本项目将用到的限流部分直接集成到代码中
3. 加入缓存预热,在秒杀开始前,将库存信息读到缓存中,并暴露数据库和缓存重置方法便于服务器部署压测
4. 缓存更新逻辑中加入 Redis 事务,避免脏数据
5. 将 Kafka-client 替换为 spring-kafka,自动配置,通过 KafkaTemplate 和 Listen 进行消息的生产和消费,采用 Gson 进行 Kafka 消息序列化和反序列化,精简大量代码
### Jmeter 压测
![](<https://github.com/gongfukangEE/gongfukangEE.github.io/raw/master/_pic/%E5%88%86%E5%B8%83%E5%BC%8F/Jmeter%20%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95%20TPS.png>)
**测试流程如下:**
首先下载 JMeter 安装包 可以去官网下载:http://jmeter.apache.org
windows 环境下载 zip 安装包,然后将下载的文件进行解压,进入 bin 目录运行 jmeter.bat 即可。
接下来是 Jmeter 测试计划设置:
(1)在测试计划上右键新建一个线程组
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/1.png>)
线程组属性内可以修改线程数、Ramp-Up 时间和循环次数。
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/2.png>)
(2)在线程组上右键添加 HTTP 请求
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/3.png>)
其属性包括 WEB 服务器的协议、服务器名称或 IP 和端口号,HTTP 请求的方法和路径。
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/4.png>)
(3)在HTTP请求上右键添加一个监听器,可以根据自己的需求添加汇总报告、查看结果树等等。
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/5.png>)
如下图所示为汇总报告,可以查看异常比例和吞吐量,方便调优。
![](<https://github.com/daydreamdev/MeetingFilm/raw/master/pic/seconds-kill/6.png>)
这样一个简单的 Jmeter 测试计划就算添加完了。一个 HTTP 请求对应一个接口,可以添加多个 HTTP 请求 以达到多个接口同时检测的需求。
### 0. 基本秒杀逻辑
```java
@Override
public int createWrongOrder(int sid) throws Exception {
// 数据库校验库存
Stock stock = checkStock(sid);
// 扣库存(无锁)
saleStock(stock);
// 生成订单
int res = createOrder(stock);
return res;
}
private Stock checkStock(int sid) throws Exception {
Stock stock = stockService.getStockById(sid);
if (stock.getCount() < 1) {
throw new RuntimeException("库存不足");
}
return stock;
}
private int saleStock(Stock stock) {
stock.setSale(stock.getSale() + 1);
stock.setCount(stock.getCount() - 1);
return stockService.updateStockById(stock);
}
private int createOrder(Stock stock) throws Exception {
StockOrder order = new StockOrder();
order.setSid(stock.getId());
order.setName(stock.getName());
order.setCreateTime(new Date());
int res = orderMapper.insertSelective(order);
if (res == 0) {
throw new RuntimeException("创建订单失败");
}
return res;
}
// 扣库存 Mapper 文件
@Update("UPDATE stock SET count = #{count, jdbcType = INTEGER}, name = #{name, jdbcType = VARCHAR}, " + "sale = #{sale,jdbcType = INTEGER},version = #{version,jdbcType = INTEGER} " + "WHERE id = #{id, jdbcType = INTEGER}")
```
### 1. 乐观锁更新库存,解决超卖问题
超卖问题出现的场景
![](https://github.com/gongfukangEE/gongfukangEE.github.io/raw/master/_pic/%E5%88%86%E5%B8%83%E5%BC%8F/%E7%A7%92%E6%9D%80%E8%B6%85%E5%8D%96.png)
悲观锁虽然可以解决超卖问题,但是加锁的时间可能会很长,会长时间的限制其他用户的访问,导致很多请求等待锁,卡死在这里,如果这种请求很多就会耗尽连接,系统出现异常。乐观锁默认不加锁,更失败就直接返回抢购失败,可以承受较高并发
![](https://github.com/gongfukangEE/gongfukangEE.github.io/raw/master/_pic/%E5%88%86%E5%B8%83%E5%BC%8F/%E4%B9%90%E8%A7%82%E9%94%81%E6%89%A3%E5%BA%93%E5%AD%98.png)
```java
@Override
public int createOptimisticOrder(int sid) throws Exception {
// 校验库存
Stock stock = checkStock(sid);
// 乐观锁更新
saleStockOptimstic(stock);
// 创建订单
int id = createOrder(stock);
return id;
}
// 乐观锁 Mapper 文件
@Update("UPDATE stock SET count = count - 1, sale = sale + 1, version = version + 1 WHERE " +
"id = #{id, jdbcType = INTEGER} AND version = #{version, jdbcType = INTEGER}")
```
### 2. Redis 计数限流
根据前面的优化分析,假设现在�
没有合适的资源?快使用搜索试试~ 我知道了~
基于 Springboot + Redis + Kafka 的秒杀系统,乐观锁 + 缓存 + 限流 + 异步,TPS 从 500...
共120个文件
xml:88个
java:20个
properties:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 179 浏览量
2024-12-26
14:33:02
上传
评论
收藏 102KB ZIP 举报
温馨提示
【资源说明】 基于 Springboot + Redis + Kafka 的秒杀系统,乐观锁 + 缓存 + 限流 + 异步,TPS 从 500 优化到 3000全部资料+详细文档+高分项目.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
资源推荐
资源详情
资源评论
收起资源包目录
基于 Springboot + Redis + Kafka 的秒杀系统,乐观锁 + 缓存 + 限流 + 异步,TPS 从 500 优化到 3000全部资料+详细文档+高分项目.zip (120个子文件)
mvnw.cmd 6KB
.gitattributes 66B
.gitignore 485B
secondkill.log.2019-06-10.0.gz 3KB
seconds-kill.iml 10KB
OrderServiceImpl.java 6KB
IndexController.java 5KB
MavenWrapperDownloader.java 5KB
RedisPoolUtil.java 3KB
SecondsKillApplicationTests.java 2KB
StockWithRedis.java 2KB
RedisPreheatRunner.java 2KB
RedisLimit.java 1KB
RedisPool.java 1KB
ConsumerListen.java 1KB
StockMapper.java 1KB
StockServiceImpl.java 1KB
OrderService.java 1KB
SecondsKillApplication.java 1014B
ScriptUtil.java 937B
StockService.java 738B
StockOrderMapper.java 727B
RedisKeysConstant.java 429B
Stock.java 310B
StockOrder.java 310B
LICENSE 1KB
limit.lua 771B
README.md 27KB
mvnw 9KB
application.properties 948B
maven-wrapper.properties 116B
项目授权码.txt 268B
workspace.xml 72KB
a2fed71b-6822-4e41-a514-8ab1d04ff389.xml 37KB
uiDesigner.xml 9KB
Project_Default.xml 9KB
pom.xml 3KB
dataSources.xml 888B
dataSources.local.xml 807B
Maven__org_springframework_boot_spring_boot_test_autoconfigure_1_5_7_RELEASE.xml 757B
Maven__org_springframework_boot_spring_boot_starter_logging_1_5_7_RELEASE.xml 736B
Maven__org_springframework_boot_spring_boot_starter_tomcat_1_5_7_RELEASE.xml 729B
Maven__org_springframework_boot_spring_boot_autoconfigure_1_5_7_RELEASE.xml 722B
Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_1_1.xml 718B
Maven__org_springframework_boot_spring_boot_starter_jdbc_1_5_7_RELEASE.xml 715B
Maven__org_springframework_boot_spring_boot_starter_test_1_5_7_RELEASE.xml 715B
Maven__org_springframework_boot_spring_boot_starter_web_1_5_7_RELEASE.xml 708B
Maven__org_springframework_spring_context_support_4_3_11_RELEASE.xml 688B
Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml 688B
Maven__org_springframework_data_spring_data_commons_1_13_7_RELEASE.xml 687B
Maven__org_springframework_data_spring_data_keyvalue_1_2_7_RELEASE.xml 687B
Maven__org_springframework_boot_spring_boot_starter_1_5_7_RELEASE.xml 680B
Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_1_1.xml 676B
Maven__org_springframework_data_spring_data_redis_1_8_7_RELEASE.xml 666B
Maven__org_springframework_boot_spring_boot_test_1_5_7_RELEASE.xml 659B
Maven__org_springframework_spring_expression_4_3_11_RELEASE.xml 653B
Maven__org_apache_tomcat_embed_tomcat_embed_websocket_8_5_20.xml 648B
Maven__org_springframework_spring_messaging_4_3_11_RELEASE.xml 646B
compiler.xml 636B
Maven__org_springframework_kafka_spring_kafka_1_1_6_RELEASE.xml 635B
Maven__org_springframework_retry_spring_retry_1_2_1_RELEASE.xml 635B
Maven__com_fasterxml_jackson_core_jackson_annotations_2_8_0.xml 632B
Maven__org_springframework_spring_context_4_3_11_RELEASE.xml 632B
Maven__org_springframework_spring_webmvc_4_3_11_RELEASE.xml 625B
Maven__org_springframework_boot_spring_boot_1_5_7_RELEASE.xml 624B
Maven__org_hibernate_hibernate_validator_5_3_5_Final.xml 622B
Maven__org_springframework_spring_beans_4_3_11_RELEASE.xml 618B
Maven__com_fasterxml_jackson_core_jackson_databind_2_8_10.xml 618B
Maven__com_alibaba_druid_spring_boot_starter_1_1_0.xml 614B
Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_20.xml 613B
Maven__org_springframework_spring_core_4_3_11_RELEASE.xml 611B
Maven__org_springframework_spring_test_4_3_11_RELEASE.xml 611B
Maven__org_springframework_spring_jdbc_4_3_11_RELEASE.xml 611B
Maven__org_springframework_spring_web_4_3_11_RELEASE.xml 604B
Maven__org_springframework_spring_aop_4_3_11_RELEASE.xml 604B
Maven__org_springframework_spring_oxm_4_3_11_RELEASE.xml 604B
Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_20.xml 599B
Maven__javax_validation_validation_api_1_1_0_Final.xml 599B
Maven__org_springframework_spring_tx_4_3_11_RELEASE.xml 597B
Maven__org_jboss_logging_jboss_logging_3_3_1_Final.xml 596B
Maven__com_fasterxml_jackson_core_jackson_core_2_8_10.xml 590B
Maven__org_apache_kafka_kafka_clients_0_10_1_1.xml 571B
Maven__mysql_mysql_connector_java_5_1_44.xml 562B
Maven__org_apache_commons_commons_pool2_2_4_2.xml 558B
Maven__ch_qos_logback_logback_classic_1_2_3.xml 556B
Maven__org_xerial_snappy_snappy_java_1_1_2_6.xml 554B
Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml 550B
Maven__org_apache_tomcat_tomcat_jdbc_8_5_20.xml 547B
Maven__org_apache_tomcat_tomcat_juli_8_5_20.xml 547B
Maven__ch_qos_logback_logback_core_1_1_11.xml 542B
Maven__org_hamcrest_hamcrest_library_1_3.xml 541B
Maven__org_mybatis_mybatis_spring_1_3_0.xml 537B
Maven__org_mockito_mockito_core_1_10_19.xml 537B
Maven__org_slf4j_jcl_over_slf4j_1_7_25.xml 536B
Maven__com_jayway_jsonpath_json_path_2_2_0.xml 534B
Maven__net_minidev_accessors_smart_1_1.xml 530B
Maven__org_skyscreamer_jsonassert_1_4_0.xml 525B
Maven__org_assertj_assertj_core_2_6_0.xml 523B
Maven__org_slf4j_jul_to_slf4j_1_7_25.xml 522B
Maven__org_hamcrest_hamcrest_core_1_3.xml 520B
共 120 条
- 1
- 2
资源评论
Yuki-^_^
- 粉丝: 3112
- 资源: 4587
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 实证研究常用代码命令完整版汇总(OLS、DID、PSM等)-最新出炉.zip
- 实证资产定价二:资产组合价差分析法(附数据与Stata代码)-最新出炉.zip
- 世界、全国、省市区外商直接投资(FDI)数据(更新至2020)-最新出炉.zip
- 世界各国普惠金融基础设施关键指标(ATM、金融机构等数量)数据-最新出炉.zip
- 数据包络(DEA)分析详细讲义(PPT版)-最新出炉.zip
- 世界各国首都点要素shp格式文件-最新出炉.zip
- 数字金融发展程度工具变量数据(与杭州、省会球面距离)-最新出炉.zip
- 数模竞赛Matlab克里金插值法递推关系式作图程序代码-最新出炉.zip
- 数字技术IPC专利分类号对应表资源-最新出炉.zip
- 数字经济综合指标数据及代码(2011-2019面板数据,Stata、Excel双版本)-最新出炉.zip
- 投入产出表直接与完全消耗系数(Stata版本)数据资源-最新出炉.zip
- 推荐!上市公司连锁股东指标Cross计算Stata代码(附2003-2022年数据)-最新出炉.zip
- 污染场地风险评估电子表格(含修正IUR值物质清单)-最新出炉.zip
- 伍德里奇计量经济学课后习题Stata代码大全-最新出炉.zip
- 文献可视化&社会网络分析软件ucinet-netdraw详细步骤全解-最新出炉.zip
- 稀缺!2008-2021年上市公司CEO社会资本数据整理及Stata代码-最新出炉.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功