基于Java + Redis + RocketMQ的库存秒杀系统设计与实现
一、秒杀场景核心挑战
-
瞬时高并发:万级QPS访问压力
-
库存准确性:避免超卖/少卖
-
系统可用性:防止雪崩效应
-
数据一致性:缓存与数据库同步
二、技术架构设计
1. 分层架构设计
用户请求│▼ 接入层(Nginx限流 + 令牌拦截)│▼ 逻辑层(Redis预扣库存 + RocketMQ异步)│▼ 数据层(MySQL最终扣减)
2. 核心流程
sequenceDiagramparticipant 用户participant 网关participant Redisparticipant RocketMQparticipant MySQL用户->>网关: 提交秒杀请求网关->>Redis: 执行预扣库存(LUA)alt 库存不足Redis-->>用户: 秒杀失败else 库存足够Redis->>RocketMQ: 发送异步消息RocketMQ-->>网关: 返回受理成功网关-->>用户: 提示排队中RocketMQ->>MySQL: 消费消息执行真实扣减end
三、核心代码实现
1. 环境依赖
<!-- Spring Boot Starter -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- RocketMQ -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.2</version>
</dependency>
2. Redis预扣库存(LUA脚本)
-- seckill.lua
local key = KEYS[1]
local quantity = tonumber(ARGV[1])
local current = tonumber(redis.call('get', key) or '0')if current >= quantity thenredis.call('decrby', key, quantity)return 1 -- 成功
elsereturn 0 -- 失败
end
3. 秒杀接口实现
@RestController
public class SeckillController {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Autowiredprivate RocketMQTemplate rocketMQTemplate;// 加载LUA脚本private static final DefaultRedisScript<Long> SECKILL_SCRIPT;static {SECKILL_SCRIPT = new DefaultRedisScript<>();SECKILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));SECKILL_SCRIPT.setResultType(Long.class);}@PostMapping("/seckill")public ResponseEntity<String> seckill(@RequestParam Long itemId, @RequestParam Integer userId) {// 1. 参数校验if (itemId == null || userId == null) {return ResponseEntity.badRequest().body("参数错误");}// 2. 执行LUA脚本预扣库存List<String> keys = Collections.singletonList("stock:" + itemId);Long result = redisTemplate.execute(SECKILL_SCRIPT, keys, "1");// 3. 处理结果if (result == 1) {// 发送MQ消息rocketMQTemplate.send("seckill_topic", MessageBuilder.withPayload(new SeckillMessage(itemId, userId)).build());return ResponseEntity.ok("秒杀请求已受理");} else {return ResponseEntity.status(429).body("库存不足");}}
}
4. RocketMQ消费者
@RocketMQMessageListener(topic = "seckill_topic",consumerGroup = "seckill_consumer_group"
)
@Service
public class SeckillConsumer implements RocketMQListener<SeckillMessage> {@Autowiredprivate StockService stockService;@Overridepublic void onMessage(SeckillMessage message) {// 数据库真实扣减stockService.reduceStock(message.getItemId());// 记录订单等后续操作...}
}
5. 数据库操作
@Service
public class StockServiceImpl implements StockService {@Autowiredprivate StockMapper stockMapper;@Transactionalpublic boolean reduceStock(Long itemId) {// 乐观锁更新int rows = stockMapper.reduceStockWithVersion(itemId);if (rows == 0) {// 库存补偿逻辑handleStockRollback(itemId);return false;}return true;}
}<!-- MyBatis Mapper -->
<update id="reduceStockWithVersion">UPDATE stock SET quantity = quantity - 1,version = version + 1WHERE item_id = #{itemId} AND quantity > 0AND version = #{version}
</update>
四、关键优化设计
1. 库存预热方案
// 活动开始前加载库存到Redis
public void preheatStock(Long itemId, Integer stock) {redisTemplate.opsForValue().set("stock:" + itemId, stock.toString());
}
2. 限流策略
// 使用Guava RateLimiter做令牌桶限流
private RateLimiter rateLimiter = RateLimiter.create(1000); // 每秒1000个请求@PostMapping("/seckill")
public ResponseEntity<String> seckill(...) {if (!rateLimiter.tryAcquire()) {return ResponseEntity.status(429).body("请求过于频繁");}// 原有逻辑...
}
3. 降级方案
@Value("${seckill.switch:true}")
private boolean seckillSwitch;@PostMapping("/seckill")
public ResponseEntity<String> seckill(...) {if (!seckillSwitch) {return ResponseEntity.status(503).body("活动暂未开始");}// 原有逻辑...
}
4. 防刷策略
// Redis记录用户访问频率
String userKey = "user_limit:" + userId;
Long count = redisTemplate.opsForValue().increment(userKey, 1);
if (count != null && count > 5) { // 每秒限制5次return ResponseEntity.status(429).body("操作过于频繁");
}
redisTemplate.expire(userKey, 1, TimeUnit.SECONDS);
五、监控与告警设计
1. 监控指标
- Redis库存余量 - MQ堆积量 - 接口QPS/TPS - 数据库连接池使用率
2. 告警规则
- MQ消息堆积超过10000条 - Redis内存使用率>80% - 接口失败率>1%
六、压测验证方案
-
JMeter压测脚本配置:
-
5000并发用户持续30秒
-
添加思考时间300ms
-
监控TPS/RT/错误率
-
-
验证指标:
- 请求成功率 ≥99.99% - 平均响应时间 <500ms - 数据库最终一致性100%
七、总结
架构优势:
-
流量分层过滤:拦截80%无效请求
-
读写分离:Redis承担99%的读压力
-
异步解耦:MQ保证最终一致性
-
柔性可用:快速失败+自动降级
扩展方向:
-
增加分布式锁防止重复下单
-
引入Sentinel实现熔断限流
-
使用Redis Cluster提升缓存容量
-
添加异步订单日志
相关文章:
基于Java + Redis + RocketMQ的库存秒杀系统设计与实现
一、秒杀场景核心挑战 瞬时高并发:万级QPS访问压力 库存准确性:避免超卖/少卖 系统可用性:防止雪崩效应 数据一致性:缓存与数据库同步 二、技术架构设计 1. 分层架构设计 用户请求│▼ 接入层(Nginx限流 令牌拦…...
hcia华为路由器静态路由实验配置
目录 一、网络拓扑分析 二、华为路由器配置(分设备) 1. R1 配置 2. R2 配置 3. R3 配置 三、验证测试 拓扑图 一、网络拓扑分析 IP 地址规划: R1:E0/0/0(12.1.1.1/24)、E0/0/1(192.168.1.…...
C语言【数据结构】:理解什么是数据结构和算法(启航)
引言 启航篇,理解什么是数据结构和算法 在 C 语言编程领域,数据结构和算法是两个核心且紧密相关的概念 一、数据结构 定义 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合(比如数组),它是组织和存储数…...
Redis7——进阶篇(五)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…...
手写svm primal form形式
svm.py import numpy as npclass SVM:def __init__(self,C1.0,lr0.01,batch_size32,epochs100):self.CCself.lrlrself.batch_sizebatch_sizeself.epochsepochsself.wNoneself.b0.0self.epoch0#计算最高得分和对应w,bdef fit(self,X,y,X_valNone,y_valNone):sample,…...
Linux中Firewall防火墙操作
一、安装Firewall命令 yum install firewalld firewalld-config二、防火墙的基本操作 1、查看防火墙状态 使用systemctl status firewalld命令可以查看firewalld服务的状态。也可以使用firewall-cmd --state命令直接查看防火墙的状态。 2、开启防火墙 * 临时性开启&…...
【MySQL】MySQL服务器——mysqld
1.MySQL服务器 是名为 mysqld 的数据库服务器程序,和“主机”(host)不一样是一个多线程的单进程管理对磁盘和内存中数据库的访问支持并发的客户端连接支持多个存储引擎,常见的存储引擎包括InnoDB、MyISAM、Memory、Archive支持事…...
VBA+FreePic2Pdf 找出没有放入PDF组合的单个PDF工艺文件
设计部门针对某个项目做了一个工艺汇总报告,原先只要几十个工艺文件,组合成一个PDF,但后来要求要多放点PDF进去,但工艺文件都混在一起又不知道哪些是重复的,找上我让我帮忙处理一下,我开始建议让她重新再组…...
windows 下用docker 部署nginx
简单版本记录,详细内容后续再写 一、拉取nginx镜像,运行 docker pull nginx 二、创建项目目录 C:\nginx-docker\ ├── html\ │ └── index.html └── conf | └── nginx.conf// index.html<!DOCTYPE html> <html> <head&g…...
云原生性能测试全解析:如何构建高效稳定的现代应用?
一、引言 随着云计算技术的快速发展,云原生(Cloud Native)架构成为现代应用开发的主流模式。云原生应用通常采用微服务架构、容器化部署,并利用 Kubernetes(K8s)等编排工具进行管理。然而,云原…...
计网面试准备
正确理解网络数据传输过程 同一路由器的不同接口属于不同局域网,广播只能在同一个局域网...
【数据分享】1999—2023年我国地级市社会消费品零售总额和年末金融机构存贷款余额(Shp/Excel格式)
在之前的文章中,我们分享过基于2000-2024年《中国城市统计年鉴》整理的1999-2023年地级市的人口相关数据、染物排放和环境治理相关数据和房地产投资情况和商品房销售面积相关指标数据(均可查看之前的文章获悉详情)! 本次我们分享…...
鸿蒙开发者社区资源的重要性
鸿蒙系统,作为华为公司自主研发的操作系统,旨在为各类智能设备提供统一的平台。它不仅支持手机、平板电脑等移动设备,还涵盖了物联网(IoT)设备和其他智能家居产品。鸿蒙系统的开发环境和工具链对于开发者来说至关重要&…...
PHP批量去除Bom头的方法
检查的代码: <?php$dir __DIR__; $files new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));foreach ($files as $file) {if ($file->isFile() && pathinfo($file, PATHINFO_EXTENSION) php) {$content file_get_contents(…...
字节攻克关键技术,大模型训练效率提升1.7倍,成本节省40%
近日,字节豆包大模型团队开源针对 MoE 架构的关键优化技术COMET,该技术可将大模型训练效率提升1.7倍,成本节省40%。据悉,该技术已实际应用于字节的万卡集群训练,累计帮助节省了数百万 GPU 小时训练算力。 MoEÿ…...
react对比vue的核心属性
Vue 常用的核心属性可以分为以下几类,并与 React 实现方式对比: 1. 核心属性 // Vue 选项式 API 常用属性 export default {props: {}, // 类似 React 的 propsdata() { return {} }, // 类似 React 的 useStatecomputed: {}, // 类似 React …...
[Pytorch报错问题解决]AttributeError: ‘nn.Sequential‘ object has no attribute ‘append‘
问题 运行深度学习代码的时候遇到了以下报错问题: Traceback (most recent call last):File "/home/anaconda3/envs/Text2HOI/lib/python3.9/site-packages/torch/autograd/grad_mode.py", line 28, in decorate_contextreturn func(*args, **kwargs)Fi…...
golang字符串常用的系统函数
1.说明 字符串在开发中,使用频率非常高,所以我们需要掌握字符串的常用方法。 2.统计字符串的长度 按字节len(str)go的编码统一为utf-8(ascii的字符 字母和数字占一个字节,汉字占三个字节) st…...
基于威胁的安全测试值得关注,RASP将大放异彩
2021年7月21日,由中国信息通信研究院(CAICT)指导、悬镜安全主办、腾讯安全协办的中国首届DevSecOps敏捷安全大会(DSO 2021)在北京圆满举办。大会以“安全从供应链开始”为主题,寓意安全基础决定“上层建筑…...
FFmpeg —— 各系统下ffmpeg硬件加速和API支持情况(文内表格形式详细阐述)
介绍 FFmpeg 作为一款功能强大的多媒体处理工具,支持多种硬件加速技术,能够显著提升视频编解码的效率,尤其是在处理高分辨率、高码率视频时表现尤为突出。不同操作系统下,FFmpeg 的硬件加速实现方式和支持的 API 各有特点。 在 Windows 系统上,FFmpeg 主要依赖 DirectX Vi…...
前端及后端实现csv文件下载功能
方法一、 前端内容: const url window.URL.createObjectURL(new Blob([res.data])); const link document.createElement(a); link.href url; const fileNameDateTime getFormattedDateTime(); const filename "用户提现列表"fileNameDateTime.csv…...
AGI大模型(2):GPT:Generative Pre-trained Transformer
1 Generative Pre-trained Transformer 1.1 Generative生成式 GPT中的“生成式”指的是该模型能够根据输入自动生成文本内容,而不仅仅是从已有的文本库中检索答案。 具体来说: 生成(Generative):GPT是一个生成…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_06带搜索功能的固定表头表格
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
MySQL再次基础 向初级工程师迈进
作者:在计算机行业找不到工作的大四失业者 Run run run ! ! ! 1、MySQL概述 1.1数据库相关概念 1.2MySQL数据库 2、SQL 2.1SQL通用语法 SQL语句可以单行或多行书写,以分号结尾。SQL语句可以使用空格/缩进来增强语句的可读性。MySQL数据库的SQL语句不区…...
使用 Doris 和 Hudi
作为一种全新的开放式的数据管理架构,湖仓一体(Data Lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求,在企业的大数据体系中已经得到越来越…...
Linux———迷你在线商城
一、项目简介 1、演示视频 商城项目演示视频 2、功能概述 用户认证管理:支持用户注册、登录和注销操作,通过SQLite数据库存储用户信息(如用户名和密码),确保用户数据的安全性和完整性。 商品展示:能够根据…...
城市林业的无声革命:人工智能与古老生态学如何重新设计城市
城市林业的无声革命:人工智能与古老生态学如何重新设计城市 在摩天大楼的阴影下,一场静悄悄的变革正在发生——它融合了硅芯片与古老根系,算法与原住民智慧。 作者:保罗桑杜 作者利用 PicLumen 创建的图像 城市森林不再只是城市…...
Linux第七讲:基础IO
Linux第七讲:基础IO 1.什么是文件2.文件操作的复习2.1文件基本操作复习2.2将信息输出到显示器,你有哪种方法2.3stdin、stdout、stderror2.4细节问题讲解 3.系统文件IO3.1open函数使用3.1.1理解标志位3.1.2权限问题3.1.3write和read接口介绍3.1.4谈谈fd以…...
【GIT】重新初始化远程仓库
有的时候我们克隆远端仓库会出错: git clone --depth 1 git116.*.*.*:/srv/customs.git D:\dev\projects\kdy\customs11\customs Cloning into D:\dev\projects\kdy\customs11\customs... remote: Enumerating objects: 1494, done. remote: Counting objects: 100…...
力扣热题 100:多维动态规划专题经典题解析
系列文章目录 力扣热题 100:哈希专题三道题详细解析(JAVA) 力扣热题 100:双指针专题四道题详细解析(JAVA) 力扣热题 100:滑动窗口专题两道题详细解析(JAVA) 力扣热题 100:子串专题三道题详细解析(JAVA) 力…...
