跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

设计支持万人并发的秒杀系统架构与实现方案

秒杀系统核心在于高并发下的库存一致性与流量削峰。架构采用分层过滤,通过 CDN 静态化、网关限流及消息队列异步处理请求。库存扣减利用 Redis 原子操作配合 Lua 脚本防止超卖,数据库层采用乐观锁兜底。系统需具备弹性伸缩能力,结合熔断降级策略保障高可用,并通过多维度监控与对账机制确保数据最终一致性。

嘘发布于 2026/3/28更新于 2026/6/818 浏览
设计支持万人并发的秒杀系统架构与实现方案

秒杀系统架构设计与核心问题解决方案

一、系统架构设计

1. 分层架构

整体采用分层过滤策略,请求流向如下:

客户端层 → 接入层 → 业务服务层 → 数据层
限流      缓存      队列        数据库

2. 具体组件

  • 客户端:静态资源 CDN 加速、倒计时校准、防重复提交。
  • 接入层:Nginx+Lua/OpenResty,负责第一层限流和缓存。
  • 业务层:秒杀服务集群(无状态)、消息队列(Kafka/RocketMQ)、缓存集群(Redis Cluster)。
  • 数据层:主从数据库(读写分离)、分库分表(按商品/时间)。

二、核心问题解决方案

1. 超卖问题

解决库存扣减的并发安全是重中之重,主要有三种思路。

Redis 原子操作

利用 Lua 脚本保证检查与扣减的原子性,避免多线程竞争。

-- 使用 Redis 的 DECR 原子操作扣减库存
def deduct_stock(product_id, user_id):
    stock_key = f"stock:{product_id}"
    lua_script = """
    local stock = tonumber(redis.call('GET', KEYS[1]))
    if stock and stock > 0 then
        redis.call('DECR', KEYS[1])
        return 1
    end
    return 0
    """
    result = redis.eval(lua_script, 1, stock_key)
    return result == 1
数据库乐观锁

作为兜底方案,在数据库层面增加版本号控制。

UPDATE products SET stock = stock - 1, version = version + 1 
WHERE id = ? AND stock > 0 AND version = ?
预扣库存

先预扣 Redis 库存,再异步同步到 DB,提升响应速度。

// 先预扣 Redis 库存,再异步同步到 DB
   {
        + productId;
       redisTemplate.opsForValue().decrement(key, count);
     (remaining >= ) {
        
        sendStockDeductMessage(productId, count);
         ;
    }  {
        
        redisTemplate.opsForValue().increment(key, count);
         ;
    }
}
public
boolean
preDeductStock
(String productId, int count)
String
key
=
"seckill:stock:"
Long
remaining
=
if
0
// 发送 MQ 消息异步扣减数据库
return
true
else
// 库存不足,回滚
return
false

2. 高并发请求处理

流量削峰

通过消息队列缓冲突发请求,将同步调用转为异步处理。

// 使用消息队列缓冲请求
@Component
public class SeckillService {
    @Autowired
    private RocketMQTemplate mqTemplate;

    public SeckillResult seckill(SeckillRequest request) {
        // 1. 校验用户和商品状态
        if (!validate(request)) {
            return SeckillResult.fail("校验失败");
        }
        // 2. 生成唯一请求 ID
        String requestId = generateRequestId(request);
        // 3. 请求入队,立即返回
        mqTemplate.sendOneWay("seckill-topic", MessageBuilder.withPayload(request).build());
        // 4. 返回排队中状态,前端轮询结果
        return SeckillResult.processing(requestId);
    }
}
分层过滤

多层拦截能有效减少无效流量到达后端核心逻辑。

所有请求 → 合法性校验 → 库存校验 → 频率控制 → 实际下单
100 万     → 50 万       → 10 万      → 5 万      → 1 万

3. 系统性能优化

缓存策略

采用多级缓存配置,平衡速度与一致性。

# 多级缓存配置
缓存层级:
一级:JVM 本地缓存 (Caffeine) - 热点商品
二级:Redis 集群 - 库存信息
三级:数据库 - 最终一致性
读多写少优化

活动开始前进行缓存预热,减少冷启动压力。

// 商品信息缓存预热
@Service
public class CacheWarmUpService {
    @PostConstruct
    public void warmUpSeckillProducts() {
        List<Product> hotProducts = loadHotProducts();
        for (Product product : hotProducts) {
            // 库存信息
            redisTemplate.opsForValue().set(
                "stock:" + product.getId(), product.getStock()
            );
            // 商品详情
            redisTemplate.opsForValue().set(
                "product:" + product.getId(), JSON.toJSONString(product)
            );
            // 使用布隆过滤器存储可售商品 ID
            bloomFilter.add(product.getId());
        }
    }
}

4. 详细实现方案

秒杀流程

完整的链路涉及风险拦截、库存判断及订单落盘。

class SeckillSystem:
    def process_seckill(self, user_id, product_id):
        # 1. 恶意请求拦截
        if not self.check_risk(user_id):
            return {"code": 403, "msg": "访问过于频繁"}
        # 2. 布隆过滤器快速判断
        if not bloom_filter.contains(product_id):
            return {"code": 404, "msg": "商品不存在"}
        # 3. 内存标记(已售罄的商品直接返回)
        if sold_out_flags.get(product_id):
            return {"code": 400, "msg": "已售罄"}
        # 4. Redis 原子扣减库存
        if not self.deduct_stock_in_redis(product_id):
            sold_out_flags[product_id] = True
            return {"code": 400, "msg": "库存不足"}
        # 5. 生成订单 ID(雪花算法)
        order_id = snowflake.generate()
        # 6. 订单信息入队
        mq.send({
            "order_id": order_id,
            "user_id": user_id,
            "product_id": product_id,
            "time": time.time()
        })
        # 7. 返回排队中
        return {
            "code": 200, "msg": "排队中",
            "order_id": order_id,
            "queue_position": get_queue_position(order_id)
        }
库存同步方案

后台服务消费消息,异步更新数据库并处理对账。

@Component
@Slf4j
public class StockSyncService {
    // 数据库最终扣减
    @Transactional
    public void syncStockToDB(String productId, int count) {
        try {
            // 数据库扣减(带重试机制)
            boolean success = productDAO.deductStock(productId, count);
            if (success) {
                // 更新 Redis 中的最终库存状态
                redisTemplate.opsForValue().set(
                    "stock_final:" + productId, getDBStock(productId)
                );
                // 删除售罄标记
                soldOutCache.remove(productId);
            }
        } catch (Exception e) {
            log.error("库存同步失败", e);
            // 记录异常,人工介入处理
            alertService.sendAlert(e);
        }
    }

    // 库存对账任务
    @Scheduled(cron = "0 */5 * * * ?")
    public void stockReconciliation() {
        List<Product> products = productDAO.getAllSeckillProducts();
        for (Product product : products) {
            Integer redisStock = getRedisStock(product.getId());
            Integer dbStock = product.getStock();
            if (!Objects.equals(redisStock, dbStock)) {
                log.warn("库存不一致:productId={}, redis={}, db={}", 
                         product.getId(), redisStock, dbStock);
                // 自动修复或报警
                fixStockInconsistency(product.getId(), dbStock);
            }
        }
    }
}

三、高可用保障

1. 限流降级策略

多维度限流规则保护系统不被瞬间流量冲垮。

# 多维度限流配置
限流规则:
用户维度:每个用户 10 次/分钟
IP 维度:每个 IP 1000 次/分钟
商品维度:每个商品 10000 次/分钟
总 QPS: 系统最大承受 50000 QPS

2. 熔断降级

当依赖服务不可用时,快速失败防止雪崩。

@RestController
@Slf4j
public class SeckillController {
    @GetMapping("/seckill/{productId}")
    @HystrixCommand(
        fallbackMethod = "seckillFallback",
        commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20")
        }
    )
    public Response seckill(@PathVariable String productId, @RequestParam String userId) {
        return seckillService.process(userId, productId);
    }

    // 降级方法
    public Response seckillFallback(String productId, String userId) {
        return Response.error("系统繁忙,请稍后重试");
    }
}

四、监控与告警

1. 关键监控指标

  • 系统层面:QPS、RT、错误率、CPU/内存使用率。
  • 应用层面:库存扣减成功率、消息堆积量。
  • 业务层面:抢购成功率、用户排队时长。

2. 监控实现

使用 Micrometer 等工具埋点记录关键行为。

@Component
public class SeckillMonitor {
    private final MeterRegistry meterRegistry;

    // 记录关键指标
    public void recordSeckill(String productId, boolean success, long cost) {
        // QPS 监控
        meterRegistry.counter("seckill.requests.total").increment();
        if (success) {
            meterRegistry.counter("seckill.success.total").increment();
        } else {
            meterRegistry.counter("seckill.fail.total").increment();
        }
        // 耗时分布
        meterRegistry.timer("seckill.process.time")
            .record(cost, TimeUnit.MILLISECONDS);
        // 库存变化
        meterRegistry.gauge("seckill.stock." + productId, getCurrentStock(productId));
    }
}

五、部署与扩展

1. 弹性扩展策略

  • 水平扩展:无状态服务可快速扩容。
  • 自动伸缩:基于 CPU 使用率或 QPS 自动扩缩容。
  • 异地多活:重要业务支持多机房部署。

2. 压测方案

模拟真实场景验证系统极限。

压测场景:
场景 1: 库存预热,10 万用户同时抢 1 万商品
场景 2: 持续高压,5 万 QPS 持续 5 分钟
场景 3: 峰值冲击,瞬间 20 万 QPS
压测目标:
成功率:>99.9%
平均 RT: <100ms
错误率:<0.1%

六、安全考虑

  • 防刷机制:验证码(峰值时降级)、设备指纹、行为分析。
  • 数据安全:关键数据加密、操作日志记录、防篡改校验。

工程实践建议

在实际落地中,架构设计的核心在于动静分离与分层削峰。静态资源如图片、描述页应提前推送到 CDN,网关层需配合 Sentinel 等组件做恶意请求拦截和总流量限制。秒杀的核心逻辑——'下单扣库存'绝不放在前台实时处理,而是进入消息队列平滑流量,后端服务按能力消费,实现削峰填谷。

针对超卖和库存扣减,推荐采用 Redis 原子操作配合 Lua 脚本,确保检查与扣减的原子性。数据库层则作为最终一致性保障,通过乐观锁兜底。对于高并发场景,除了限流,还需注意热点 Key 的处理,可通过 Key 散列分散压力至多个 Redis 节点。

细节方面,前端加入计算型验证码防止机器人,下单前校验用户资格。服务端返回排队 ID,前端轮询结果,避免长时间阻塞。同时建立定时对账任务,核对 Redis、数据库库存和订单状态,确保极端情况下的数据修复能力。若 Redis 或数据库访问慢,要有熔断机制,防止服务被拖垮,必要时可降级为静态页面提示售罄。

目录

  1. 秒杀系统架构设计与核心问题解决方案
  2. 一、系统架构设计
  3. 1. 分层架构
  4. 2. 具体组件
  5. 二、核心问题解决方案
  6. 1. 超卖问题
  7. Redis 原子操作
  8. 数据库乐观锁
  9. 预扣库存
  10. 2. 高并发请求处理
  11. 流量削峰
  12. 分层过滤
  13. 3. 系统性能优化
  14. 缓存策略
  15. 多级缓存配置
  16. 读多写少优化
  17. 4. 详细实现方案
  18. 秒杀流程
  19. 库存同步方案
  20. 三、高可用保障
  21. 1. 限流降级策略
  22. 多维度限流配置
  23. 2. 熔断降级
  24. 四、监控与告警
  25. 1. 关键监控指标
  26. 2. 监控实现
  27. 五、部署与扩展
  28. 1. 弹性扩展策略
  29. 2. 压测方案
  30. 六、安全考虑
  31. 工程实践建议
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • C++ 仿函数详解:让对象像函数一样调用
  • 适合程序员的 7 款高效 AI 开发工具
  • AI Skill 开源合集:角色蒸馏与全场景生产级技能
  • Linux 匿名管道通信:原理与代码实战
  • 算法:双指针法详解(上)
  • 在 Cursor 中配置并使用 MCP 服务实战指南
  • WebGL 缓冲区使用与多点绘制实战
  • Whisper-large-v3 云端部署详细步骤
  • Stable Diffusion XL 1.0 部署:阿里云 PAI-EAS 服务封装与 Web 应用构建
  • Barrier 跨平台 KVM 软件使用教程
  • Kimi Code AI 编程助手功能与集成详解
  • llama.cpp 本地大模型部署教程
  • 本地部署 Llama3-8B 大模型实战指南
  • 从零开始学习 Python 自动化测试开发指南
  • 网络、运维与安全基础技术词汇汇总
  • 十年前端技术之旅回顾:从 jQuery 到 Vue 的演进
  • AI Agent 架构:基础组成模块深度解析
  • Seedream 4.0 企业级图像生成能力与应用场景解析
  • 千笔 AI 学术写作工具核心功能解析
  • Python MCP 实战:构建 FastAPI 服务端与客户端示例
  • 相关免费在线工具

    • Keycode 信息

      查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

    • Escape 与 Native 编解码

      JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

    • JavaScript / HTML 格式化

      使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

    • JavaScript 压缩与混淆

      Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

    • 加密/解密文本

      使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

    • Gemini 图片去水印

      基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online