解决秒杀高并发的一些方案

news/2025/9/29 18:22:43/文章来源:https://www.cnblogs.com/wangzhaobo/p/19119274

解决秒杀高并发的一些方案

秒杀场景的特点:

  • 瞬时高并发:大量请求在短时间内涌入
  • 库存有限:必须避免超卖
  • 一致性要求高:库存扣减和订单生成要保证正确

常见的几种实现方式:


一、Redis 方案(基于内存,效率高)

1. 库存预热队列

活动前把商品库存预先放入 Redis 队列,抢购时依次弹出。

// 预热库存
for ($i=0; $i<$count; $i++) {$redis->lpush('goods_store', 1);
}// 抢购时
$count = $redis->lpop('goods_store');
if (!$count) {insertLog('error:no store redis');return;
}
  • ✅ 优点:

    • FIFO 保证“先到先得”,不会超卖
    • 实现简单直观
  • ⚠️ 缺点:

    • 大量库存预热占用内存
    • Redis 宕机可能导致数据丢失
    • 需要定期与数据库对账,保持一致性

2. 分布式锁 (setnx)

do {$res = $redis->setnx("numKey", 1);$this->timeout -= 100;usleep(100);
} while ($res == 0 && $this->timeout > 0);if ($res == 0) {echo 'fail1';
} else {$num = $redis->get('num');if ($num > 0) {$redis->decr('num');$res = $redis->lPush('result', $num);echo $res ? "success:".$num : "fail2";} else {echo "fail3";}$redis->del("numKey");
}
  • ✅ 优点:

    • 保证并发情况下操作的互斥性
  • ⚠️ 缺点:

    • setnx 需搭配 expire,否则进程异常会死锁
    • 自旋锁 + usleep 性能浪费
    • 建议用 SET key value NX EX ttlRedLock 替代

3. 原子计数 (decr)

$retNum = $redis->decr('num');
if ($retNum >= 0) {// success
} else {// fail
}
  • ✅ 优点:

    • Redis 原子操作,性能极高
    • 实现最简洁
  • ⚠️ 缺点:

    • 仍需防止 retNum == -1 的情况(超卖)
    • Redis 数据和 MySQL 数据需异步对账

4. 乐观锁 (watch)

$num = $redis->get('num');
if ($num > 0) {$redis->watch('num');$res = $redis->multi()->decr('num')->lPush('result', $num)->exec();echo $res ? "success:".$num : "fail1";
} else {echo "fail2";
}
  • ✅ 优点:

    • CAS 思路,避免加锁
  • ⚠️ 缺点:

    • watchexec 之间容易冲突,失败率高
    • 高并发下需大量重试,性能差

二、MySQL 方案(简单,但效率差)

1. 悲观锁

SELECT stock 
FROM goods 
WHERE id = [商品ID] 
FOR UPDATE;
  • ✅ 优点:

    • 保证强一致性,逻辑简单
  • ⚠️ 缺点:

    • 高并发下阻塞严重,吞吐量极低
    • 一般只用于小规模并发或后台

2. 乐观锁(版本号 / 时间戳)

UPDATE goods 
SET stock = stock - 1, version = version + 1 
WHERE id = [商品ID] AND stock > 0 AND version = $currentVersion;
  • ✅ 优点:

    • 非阻塞,性能比悲观锁好
    • 并发下保证库存不超卖
  • ⚠️ 缺点:

    • 更新失败需业务层重试
    • 用户体验可能不佳(抢到也可能失败)

三、文件锁(不推荐)

1. 排他锁

$fp = fopen("lock.txt", "w+");
if (!flock($fp, LOCK_EX | LOCK_NB)) {echo "系统繁忙,请稍后再试";return;
}
  • ✅ 优点:

    • 实现简单,测试方便
  • ⚠️ 缺点:

    • 仅适合单机环境
    • IO 开销大,性能差
    • 生产环境基本不用

四、消息队列削峰(MQ)

思路:前端请求先进入 MQ(Kafka / RabbitMQ / RocketMQ),消费者再按顺序从队列中取出请求处理。

  • ✅ 优点

    • 削峰填谷,抵御流量洪峰
    • 系统解耦,请求不会直接打爆数据库
    • 易于扩展(消费者可水平扩展)
  • ⚠️ 缺点

    • 处理有一定延迟(最终一致性)
    • 消息丢失/重复需要保证幂等性

👉 实际上,Redis 扣减库存 + MQ 异步下单 是大厂标配方案。


五、令牌桶 / 漏桶限流

思路:在入口层(Nginx / API Gateway)加限流,比如 每秒只发放 100 个令牌,拿到令牌的请求才能继续执行。

  • ✅ 优点

    • 限制瞬时并发,保护下游服务
    • 拒绝多余请求,避免系统雪崩
  • ⚠️ 缺点

    • 抢不到令牌的用户直接失败(但符合秒杀场景特点)

六、预扣库存(缓存 + 数据库双写)

思路:活动开始前,将库存同步到 Redis,Redis 负责实时扣减,后台定时把结果异步写回 MySQL。

  • ✅ 优点

    • Redis 抗高并发,性能优
    • MySQL 保存最终结果,保证持久化
  • ⚠️ 缺点

    • 需要处理 Redis 与 MySQL 不一致问题
    • 可能出现超卖或少卖,需要补偿机制

七、用户排队(异步处理)

思路:先让用户进入排队系统(类似 12306 / JD 抢购),后台分批处理订单请求。

  • ✅ 优点

    • 用户体验较好,有“排队感知”
    • 系统压力均匀,不会瞬间打爆
  • ⚠️ 缺点

    • 实现复杂,需要额外的排队服务
    • 用户下单延迟高

八、静态页面 + 前端限流

思路:活动页提前生成静态页面,减少数据库和应用层压力。前端在秒杀按钮处增加限流逻辑(例如按钮灰化、随机延迟)。

  • ✅ 优点

    • 最大化减少应用层压力
    • 提前过滤一部分无效请求
  • ⚠️ 缺点

    • 不适合高安全性场景(前端逻辑容易被绕过)
    • 只能作为“辅助手段”

九、CDN 缓存 + 本地化校验

思路:把活动页、秒杀时间、商品信息放到 CDN,本地浏览器校验秒杀开始时间,减少集中请求的瞬时流量。

  • ✅ 优点

    • 降低源站压力
  • ⚠️ 缺点

    • 无法替代库存扣减逻辑,只能减少部分请求

十、硬件层面的支持

  • 内核调优(Linux TCP 参数、文件句柄数等)
  • 负载均衡(Nginx / LVS)
  • 分库分表 / 读写分离
  • 热点数据隔离(比如单独 Redis 实例处理秒杀库存)

总结与推荐实践

  • Redis 原子操作(decr 或 队列) → 负责扣减库存 + 限流,保证不超卖
  • 消息队列(Kafka/RabbitMQ) → 负责削峰填谷,把订单请求异步落库
  • MySQL 乐观锁 → 负责最终一致性,防止异常情况导致超卖
  • 消息队列削峰(Kafka / RabbitMQ)
  • 入口限流(令牌桶 / 漏桶)
  • 排队系统(用户体验层面)
  • CDN + 静态化(减少请求风暴)
  • 系统层面优化(分库分表 / 负载均衡 / 内核优化)

额外注意事项:

  • 接口限流(令牌桶/漏桶)
  • 防刷机制(限制 IP/用户频率)
  • 幂等性(同一用户不能重复下单)
  • Redis 与 MySQL 数据定期对账

最终架构推荐: Redis + MQ + MySQL 组合拳,既能抗高并发,又能保证数据安全。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多级缓存(Memory+Regdis)

多级缓存(Memory+Regdis)根据WebAPI更改,请参考上一章节 在大并发模式下,我们可以除了数据库存,再加上本地的内存缓存查询,或分布式查询 把内存+分存式查询放在一起,叫做多级缓存。 1. 内存查询先在NuGet中引用Mi…

构建移动网关:Air780EPM用4G为WiFi和LAN设备供网

利用Air780EPM开发板,可构建一个便携式移动网关,以4G网络为出口,为WiFi和以太网设备提供即插即用的互联网接入服务。 一、多网融合概述 Air780EPM 开发板通过多网融合技术将不同类型的通信网络(4G、以太网)整合在…

9.29模拟赛总结

赛前 刚哥说要以正式考试的心态打模拟赛 所以提前设了一个目标,230+和rk<=5 然后和大赛前一样,先调整状态,深呼吸什么的 赛时 开始时还剩3:45时间 T1上来分析了一下性质 在3:24时秒了 T2看见直径,然后直接想端…

优化 if/else 的四种设计模式

在日常开发中,我们经常会遇到需要根据不同条件执行不同逻辑的场景,导致代码中出现大量的if/else嵌套。这不仅降低了代码的可读性和可维护性,还会增加后续扩展的难度。 本文将介绍四种优雅的设计模式来优化这种"…

多corner综合

综合时指定多个cornet的工艺库进行分析一般一个工艺会提供不同工艺角的标准单元库,如果希望在综合的时候能在两个边界工艺库上做分析,可以利用set_min_library和set_operating_conditions两个命令。 set_min_library…

Day11-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\oop\demo06

多态 动态编译 指的是,同一方法可以根据发送对象的不同而采取多种不同的行为方式 instanceof (类型转换)引用类型,判断一个对象是什么类型 /* 多态注意事项多态是方法的多态,属性没有多态 父类和子类,有联系 类…

注册网站域名需要什么网站更换图片之类的怎么做

在 VSCodium 中安装仓颉编程语言的插件 VSCodium是基于微软编辑器 VS Code源代码编译制作&#xff0c;去掉了微软的遥测功能&#xff0c;是一个由社区驱动、自由许可的二进制发行版。 仓颉编程语言的开发插件是一个需要从本地安装的插件。其官方网站上&#xff0c;写出了其安装…

牛客周赛 Round 111

https://ac.nowcoder.com/acm/contest/117763 E 在此题中,我们认为数组以从左到右的顺序排列。 对于一个数组 \(a\),小芳定义两个函数 \(L\left( a\right)\) 与 \(R\left( a\right)\) 为: \(\hspace{23pt} \bullet\…

高端母婴网站模板网络营销渠道

云原生专栏大纲 文章目录 准备工作项目结构介绍配置安全测试ConfigMapSecret使用Secret中数据的方式Deployment使用Secret配置Secret加密 kustomize部署清单ConfigMap改造SecretSealedSecretDeployment改造Serviceistio相关资源DestinationRuleGatewayVirtualServiceServiceAc…

OpenLayers地图交互 -- 章节十一:拖拽材料交互详解

OpenLayers地图交互 -- 章节十一:拖拽材料交互详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

2025年人工智能与智能装备国际学术会议(AIIE 2025)

2025年人工智能与智能装备国际学术会议(AIIE 2025) 2025 International Conference on Artificial Intelligence and Intelligent Equipment 在这里看会议官网详情 时间:2025年11月7日-9日 地点:中国西安 本轮截稿…

详细介绍:衡石HQL深度解析:如何用类SQL语法实现跨源数据的高效联邦查询?

详细介绍:衡石HQL深度解析:如何用类SQL语法实现跨源数据的高效联邦查询?2025-09-29 18:00 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x:…

通过IDOR实现权限提升导致未授权用户注入

本文详细介绍了作者在公开漏洞赏金项目中发现的IDOR漏洞,通过修改contactId参数实现权限提升,能够将任意用户添加到设备管理组中,获得了相应的漏洞赏金。通过IDOR实现权限提升导致未授权用户注入 再次问候,我是Oma…

APUE学习笔记之基础知识(一) - Invinc

本文记录《UNIX环境高级编程》第3版中第1章 基础知识 的一些知识点。 包括UNIX体系结构和登录、文件和目录、输入和输出、程序和进程、出错处理、用户标识、信号、时间值、系统调用和库函数等基本概念。本文记录《UNIX…

Syslog日志集成搭建

搭建一个完整的 syslog → Filebeat → Elasticsearch → Kibana 测试环境,详细的分步骤配置手册,包括 Linux (Filebeat) 和 Windows (Elasticsearch + Kibana) 的安装和配置。 部署架构 Filebeat:运行在 Linux 服务…

拿别的公司名字做网站工业互联网平台首先要提高数据的挖掘能力

当string&#xff0c;number函数不被用作构造函数的可以当成转换函数 如 string(false),number(‘3’),boolean([]) Object(3) new number(3); 除了NULL和undefined以外任何值都具有toString()方法 JS 在执行程序的时候会自动检测表达式来进行变量转换。 显示转换变量&#xf…

定义工业生产新范式!网易灵动发布全球首款全域智能无人装载机“灵载”

近日,在全球最具影响力的工程机械盛会——BICES 2025现场,网易旗下工程机械智能化品牌网易灵动隆重召开无人装载机智能解决方案发布会,正式推出全球首款面向全域场景的具身智能无人装载机——“灵载”。 此次发布标…

国有银行人力资源数字化转型的合规突围与效能跃迁

在数字化浪潮下,金融行业正面临深刻变革。作为数字中国建设的重要支撑,国家金融数字化战略明确要求银行体系充分应用数字技术,优化服务模式、提升管理效能。国有银行作为金融体系的中流砥柱,不仅需要驱动外部服务数…

深圳网站商城定制设计邯郸招聘网最新招聘信息2023

本页包含内容&#xff1a; 术语赋值运算符算术运算符组合赋值运算符比较运算符三目运算符空合运算符区间运算符逻辑运算符 运算符是检查、改变、合并值的特殊符号或短语。例如&#xff0c;加号&#xff08;&#xff09;将两个数相加&#xff08;如 let i 1 2&#xff09;。更…

Java 类类型

Note: This article has been written with the assistance of AI.普通类 (Regular Class) 类的定义和基本结构 类的定义语法 [访问修饰符] class 类名 [extends 父类] [implements 接口1, 接口2, ...] {// 成员变量//…