Skip to content

常见面试场景题 ​

1. 秒杀系统如何设计? ​

核心思想:分层拦截流量、缓存扛住并发、异步削峰填谷、兜底保障可用,最终只有极少量请求落到数据库。

一、前端与 CDN 层:拦截第一层无效流量 ​

目标:拦截 90% 以上的无效请求,避免流量直接冲击后端

  1. 页面静态化:秒杀商品页全量静态化部署到 CDN,仅倒计时、库存等动态数据通过接口异步拉取
  2. 前端控频:秒杀按钮倒计时置灰,点击后立即禁用,前端限制 5 秒内重复点击无效
  3. 接口隐藏:秒杀开始前不返回真实下单地址,开始时通过接口动态获取,防止脚本提前刷接口
  4. 验证码拦截:下单前增加图形 / 滑块验证码,拉长请求间隔,打击机器批量刷单

二、接入层(Nginx / 网关):第二层流量管控 ​

目标:进入应用服务前过滤非法请求,控制总入口流量

  1. Nginx 限流:用limit_req_zone做单 IP 秒级限流,拦截高频恶意 IP;limit_conn_zone限制单 IP 连接数

  2. 负载均衡:多实例部署应用服务,Nginx 轮询分发,分散单节点压力

  3. 网关统一管控(Spring Cloud Gateway):

    • 统一鉴权、参数校验,过滤非法格式请求
    • 分布式限流:基于 Redis Lua 实现商品维度令牌桶限流,精准控制每秒进入核心接口的请求量
    • 黑白名单:实时封禁异常 IP / 账号

三、服务层:核心接口防护与流量削峰 ​

目标:控制进入核心业务的并发量,避免服务雪崩

  1. 接口幂等:每个用户 + 商品生成唯一请求流水号,Redis 存seckill:req:{流水号}去重,重复请求直接拒绝
  2. 限购校验:Redis 记录用户购买次数seckill:user:{goodsId}:{userId},达到限购上限直接返回失败
  3. 同步转异步:下单请求不直接写库,Redis 扣减库存成功后,将订单信息投递到消息队列(RocketMQ/RabbitMQ),立即返回用户「排队中」
  4. 熔断降级:集成 Sentinel/Hystrix,非核心接口(用户信息、商品推荐)直接降级返回兜底数据;核心接口异常时快速失败,防止级联故障

四、库存层:Redis 预扣减(解决超卖核心) ​

目标:用 Redis 扛住高并发库存读写,从根源杜绝超卖

  1. 库存预热:秒杀开始前,通过定时任务将商品库存预热写入 Redis(String 结构:seckill:stock:{goodsId})

  2. 原子扣减:使用Redis Lua 脚本

    实现「库存判断 + 扣减」原子操作,保证并发下零超卖

    lua
    -- 入参:KEYS[1] = 库存key
    local stock = tonumber(redis.call('get', KEYS[1]))
    if stock <= 0 then return 0 end
    redis.call('decr', KEYS[1])
    return 1
  3. 此阶段只操作缓存库存,不直接操作 MySQL,将高并发完全拦截在缓存层

五、订单层:异步落库与最终一致性 ​

目标:解耦核心链路,保证数据最终一致

  1. 消息生产:Redis 扣减库存成功后,生成带唯一订单号的下单消息,投递到 MQ
  2. 消息消费:独立订单消费服务监听队列,串行执行下单流程:
    • 幂等校验:根据订单号去重,防止消息重复消费
    • 生成订单:写入 MySQL 订单表
    • 扣减数据库库存:执行真实库存扣减
  3. 一致性保障:
    • 消息重试 + 死信队列:消费失败自动重试,超次数进入死信队列人工处理
    • 定时对账:定时任务对比 Redis 库存与 MySQL 库存,不一致时自动校准回补

六、数据库层:落地优化与兜底 ​

目标:保证数据落库稳定,扛住最终收敛后的流量

  1. 库存扣减兜底:MySQL 层面用

    乐观锁(版本号)

    兜底,避免数据库层面超卖

    sql
    UPDATE goods_stock 
    SET stock = stock - 1, version = version + 1 
    WHERE goods_id = ? AND version = ? AND stock > 0
  2. 分库分表:订单表按用户 ID / 商品 ID 分片,分散单库写入压力

  3. 读写分离:订单查询、库存查询走从库,写入操作走主库

  4. 连接池优化:合理配置 Druid/HikariCP 参数,避免连接耗尽

七、安全风控:防刷与防攻击 ​

目标:拦截恶意刷单、脚本篡改、重放攻击

  1. 接口签名:请求携带timestamp + nonce + sign,服务端校验签名,时间差超过 5 秒直接拒绝
  2. 风控规则:实时检测单 IP / 账号请求频率、请求特征,异常行为直接封禁
  3. 防重放:nonce 值存入 Redis,有效期内重复请求直接拦截

八、兜底预案与高可用 ​

目标:极端故障下保证核心链路可用,不发生雪崩

  1. Redis 故障降级:Redis 集群不可用时,降级为直接操作 MySQL 乐观锁扣库存,同时网关层大幅限流
  2. MQ 故障降级:MQ 不可用时,异步下单切为同步下单,同时调低限流阈值保护数据库
  3. 全链路降级:峰值时关闭非核心功能(积分、优惠券、推荐),只保留秒杀核心链路
  4. 监控告警:接入 Prometheus+Grafana,监控 QPS、库存、订单量、响应时间,异常阈值触发告警

九、压测与调优 ​

目标:验证系统承载能力,定位性能瓶颈

  1. 全链路压测:使用 JMeter/Wrk 模拟百万级并发,覆盖从入口到数据库的完整链路
  2. 核心调优方向:
    • JVM:合理设置堆内存,使用 G1/ZGC 回收器,优化 GC 停顿
    • Redis:集群部署,关闭不必要持久化,使用 Pipeline 批量操作
    • 服务:优化 Tomcat 线程池、业务线程池参数,减少锁竞争
    • 数据库:索引优化、事务隔离级别调整、慢 SQL 治理

如有转载或 CV 的请标注本站原文地址

访客数 --| 总访问量 --