Java + MySQL + Redis 构建高并发秒杀系统实战(乐观锁/悲观锁/接口限流)
下面给你一套非常硬核、毕设/面试双杀的方案《基于 Java MySQL Redis 的高并发秒杀系统实战》✅ 支持乐观锁 / 悲观锁 / Redis 预减库存 / 接口限流✅ 技术深度够答辩老师基本不会为难你✅ 可以直接当毕设 / 课程设计 / 技术博客 / 面试项目一、业务场景以「商品秒杀」为例商品库存100 件瞬时并发10000 请求核心问题超卖库存 0重复下单数据库被打爆接口被刷二、技术架构客户端 ↓ Nginx负载均衡 ↓ SpringBoot ├── 接口限流Redis Lua ├── 秒杀接口 │ ├── Redis 预减库存 │ └── MQ 异步下单可选 ├── 库存回滚 ↓ MySQL订单 / 商品 Redis缓存 计数 限流技术作用SpringBoot快速开发Redis缓存、预减库存、限流MySQL持久化MyBatisORMRedisson / Lua分布式锁RabbitMQ可选异步削峰三、数据库设计极简但够用1️⃣ 商品表seckill_productCREATE TABLE seckill_product ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100), stock INT, price DECIMAL(10,2), start_time DATETIME, end_time DATETIME );2️⃣ 订单表seckill_orderCREATE TABLE seckill_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, product_id BIGINT, create_time DATETIME );四、核心流程答辩必画用户请求秒杀 ↓ 接口限流Redis ↓ Redis 预减库存 ↓ 库存 ≤ 0 → 直接拒绝 ↓ MySQL 乐观锁 / 悲观锁扣库存 ↓ 下单成功五、四种核心技术方案⭐重点✅ 方案一悲观锁MySQLSELECT stock FROM seckill_product WHERE id 1 FOR UPDATE;Transactional public boolean seckill(Long userId, Long productId) { Product p productMapper.selectForUpdate(productId); if (p.getStock() 0) return false; productMapper.decreaseStock(productId); orderMapper.insert(userId, productId); return true; }缺点串行化高并发性能差✅ 方案二乐观锁版本号 / 库存字段SQLUPDATE seckill_product SET stock stock - 1, version version 1 WHERE id #{id} AND stock 0 AND version #{oldVersion};Javaint rows productMapper.decreaseStockOptimistic( productId, oldVersion); if (rows 0) { throw new RuntimeException(并发冲突秒杀失败); }优点并发性能更好老师最爱问ABA 问题可答秒杀场景影响不大✅ 方案三Redis 预减库存⭐核心Long stock redisTemplate.opsForValue() .decrement(stock: productId); if (stock 0) { redisTemplate.opsForValue() .increment(stock: productId); return 秒杀结束; }作用挡住 90% 无效请求保护数据库✅ 方案四接口限流Redis LuaLua 脚本原子性local key KEYS[1] local limit tonumber(ARGV[1]) local current tonumber(redis.call(get, key) or 0) if current 1 limit then return 0 end redis.call(incr, key) redis.call(expire, key, 1) return 1Java 调用Long result redisTemplate.execute( redisScript, Collections.singletonList(seckill:limit: userId), 1 ); if (result 0) { return 操作太频繁; }作用防止用户重复刷接口六、完整秒杀接口整合版PostMapping(/seckill) public String seckill(Long userId, Long productId) { // 1. 限流 if (!rateLimiter.tryAcquire(userId)) { return 操作频繁; } // 2. Redis 预减库存 Long stock redisTemplate.opsForValue() .decrement(stock: productId); if (stock 0) { return 已售罄; } // 3. MySQL 乐观锁扣库存 Product p productMapper.selectById(productId); int rows productMapper.decreaseStockOptimistic( productId, p.getVersion()); if (rows 0) { redisTemplate.opsForValue() .increment(stock: productId); return 秒杀失败; } // 4. 下单 orderMapper.insert(userId, productId); return 秒杀成功; }七、缓存预热重要PostConstruct public void initStock() { Product p productMapper.selectById(1L); redisTemplate.opsForValue() .set(stock:1, p.getStock()); }八、系统特色⭐答辩必讲✅ Redis 预减库存数据库保护✅ 乐观锁 悲观锁对比分析✅ Redis Lua 原子限流✅ 可扩展 MQ 异步下单✅ 高并发场景真实落地✅ 技术深度明显高于普通 CRUD 项目九、性能对比论文 / 答辩加分方案QPS是否超卖无锁高✅ 超卖悲观锁低❌乐观锁中❌Redis 乐观锁高❌十、毕设论文结构建议章节内容第1章绪论第2章相关技术第3章需求与场景分析第4章系统设计第5章核心实现四种方案对比第6章压力测试JMeter第7章总结十一、可扩展方向工作量拉满✅ RabbitMQ 异步下单✅ 分布式锁Redisson✅ 分库分表✅ 秒杀页面静态化✅ 恶意请求风控✅ 微服务化Sentinel十二、我可以继续帮你做的事 ✅✅ 给你完整 SpringBoot 秒杀项目✅ 写第4 / 第5 / 第6 章论文✅ 画架构图 / 时序图✅ 写JMeter 压测方案✅ 准备答辩老师常问问题✅ 改成分布式 / 微服务版你现在处于开题 / 中期 / 快答辩了 / 面试准备告诉我我按你的目标给你“直接能交的内容”。