51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在佳都科技的智能轨道交通项目中,自动售检票系统(AFC)在高峰时段(如早高峰)面临秒杀场景,单次请求峰值可达10万TPS,且要求99.9%的可用性。请设计一个高并发秒杀系统架构,并说明核心组件的设计思路、数据一致性保障机制以及容错策略。

佳都科技解决方案工程师/售前工程师等难度:困难

答案

1) 【一句话结论】
采用微服务拆分+分布式架构,通过Nginx+LVS负载均衡(加权轮询+IP Hash)、多级缓存(本地+Redis集群,随机过期防雪崩)、Kafka异步解耦(副本因子3+按线路分区)、ShardingSphere分库分表(按线路分库、站点分表),结合限流熔断降级及订单幂等性设计,确保10万TPS请求和99.9%可用性。

2) 【原理/概念讲解】
老师讲解:高并发秒杀系统需应对“请求量巨大、响应时间短、系统稳定性”三大挑战。架构设计核心是“分而治之”(拆分服务、分库分表)和“异步解耦”(消息队列)。

  • 负载均衡:Nginx(加权轮询,根据后端服务健康状态分配流量)+ LVS(IP Hash,按客户端IP分配请求,保证会话一致性),避免单点压力。
  • 缓存策略:
    • 本地缓存(Java本地缓存):速度快,但无法横向扩展,缓存失效后全量走数据库,易引发“缓存雪崩”(类比“所有超市同时断货,顾客涌入原产地抢购”)。
    • 分布式缓存(Redis集群):支持高并发读写,可水平扩展,需通过**分布式锁(Redis SETNX)**避免“缓存击穿”(热点数据缓存过期,第一次请求时数据库压力极大,类比“热门商品库存告急,所有顾客涌向仓库提货”)。
    • 防雪崩:分布式缓存设置随机过期时间(如TTL=5s+[-3,3]秒随机偏移),避免集中失效。
  • 消息队列:Kafka(副本因子3,持久化消息防丢失),将请求处理与订单存储解耦(用户下单后快速返回,订单异步写入队列,避免请求阻塞,类似“快递员取件后,用户端显示‘下单成功’,实际订单由后台消费者处理”)。
    • 积压应对:消费者动态扩容(根据队列长度调整数量,如队列长度>1000则增加消费者实例),或设置消息重试机制(失败后重试3次)。
  • 数据库分库分表:按业务维度(线路/站点)分库(如北京地铁1号线数据单独一个库),按站点ID分表(如station2对应表t_stock,分片规则为station_id%100),减少单库压力;读写分离(主库写订单,从库读库存),提升读性能。
  • 幂等性:订单号唯一性(数据库订单表主键为订单号),或分布式锁(Redis SETNX)保证同一订单号只处理一次,防止重复提交和超卖。

3) 【对比与适用场景】

策略/组件定义特性使用场景注意点
负载均衡Nginx(加权轮询)+ LVS(IP Hash)Nginx:动态调整后端权重,LVS:按IP分配,保证会话请求量极大(如秒杀),需高可用Nginx需配置健康检查(如检查后端服务端口响应),LVS需配置虚拟IP和真实IP列表
缓存策略本地缓存(Java本地缓存) vs 分布式缓存(Redis集群)本地缓存:速度快,无网络延迟;分布式缓存:支持高并发读写,可水平扩展请求量极大(如秒杀),需分布式本地缓存:缓存失效后全量走数据库,易雪崩;分布式缓存:需分布式锁防击穿,设置随机过期时间防雪崩
消息队列类型同步队列(RabbitMQ同步模式) vs 异步队列(Kafka)同步:请求处理同步,保证顺序;异步:解耦请求与处理,支持高吞吐请求处理时间长(如订单存储),需削峰同步队列:可能导致请求积压,系统阻塞;异步队列:需消息持久化防丢失,消费者动态扩容防积压
数据库分库分表按业务维度(线路/站点)分库分表(ShardingSphere实现)水平扩展数据库容量,读写分离读请求远多于写请求(如库存查询)从库数据延迟(秒级),需考虑一致性;分库分表规则需结合业务场景(如线路ID作为分库键,站点ID作为分表键)

4) 【示例】
用户请求购票流程(含幂等性、缓存雪崩、消息队列积压处理)

用户请求:POST /buyTicket?order_id=123456&line=1&station=2&quantity=1
1. 负载均衡(Nginx)分发请求至后端服务(AFC服务)  
2. 后端服务检查订单幂等性:  
   - 若数据库存在order_id=123456的订单,直接返回“已下单”  
   - 否则继续处理  
3. 后端服务查本地缓存(key: "line1:station2:stock"):  
   - 若存在且有效:判断票数>0则扣减(本地缓存更新),否则返回“售罄”  
   - 若不存在/过期:通过分布式锁(Redis SETNX "lock:line1:station2" 1 10s)查询Redis集群票数  
4. 分布式缓存结果:  
   - 有库存:更新缓存(SET "line1:station2:stock" 99),返回“成功”  
   - 无库存:返回“售罄”  
5. 成功后,订单信息写入Kafka(主题:order:line1:station2,消息体:{order_id:123456, line:1, station:2, quantity:1},副本因子3)  
6. 后端返回“购票成功”,用户端显示订单号  
7. 消费者(订单处理服务)从队列读取消息:  
   - 若队列长度>1000,动态扩容消费者(增加消费者实例)  
   - 执行数据库事务(插入订单+更新库存,主库写订单,从库读库存),并通知用户  

5) 【面试口播版答案】
面试官您好,针对AFC秒杀系统的高并发场景(10万TPS、99.9%可用性),我设计的架构核心是微服务拆分+分布式架构,通过Nginx+LVS负载均衡(加权轮询+IP Hash)、多级缓存(本地+Redis集群,分布式缓存设置随机过期时间防雪崩)、Kafka异步解耦(副本因子3+按线路分区)、ShardingSphere分库分表(按线路分库、站点分表),结合限流、熔断、降级及订单幂等性设计。具体来说:请求由Nginx负载均衡分发,后端服务先查本地缓存,若失效则通过分布式锁查询Redis集群票数;订单处理异步写入Kafka,消费者动态扩容处理积压;数据库按线路分库、站点分表,主库写订单,从库读库存。数据一致性采用最终一致性,通过消息持久化和事务补偿保障;容错策略包括限流(令牌桶防流量激增)、熔断(Hystrix隔离故障)、降级(库存不足时返回“售罄”),确保系统稳定。

6) 【追问清单】

  • 问题1:负载均衡的具体算法及配置?
    回答要点:Nginx采用加权轮询(根据后端服务健康状态调整权重),LVS采用IP Hash(按客户端IP分配请求,保证会话一致性),并配置健康检查(如检查后端服务端口响应)。
  • 问题2:消息队列的持久化配置及分区设计依据?
    回答要点:Kafka副本因子设为3(持久化消息,防单点故障),分区数按线路数设计(如每条线路1个分区,提升并行处理能力,如北京地铁1号线对应1个分区)。
  • 问题3:数据库分库分表的具体实现工具及规则?
    回答要点:使用ShardingSphere实现,按线路ID分库(如line1对应db1),按站点ID分表(如station2对应表t_stock,分片规则为station_id%100),结合读写分离(主库写订单,从库读库存)。
  • 问题4:99.9%可用性的保障措施?
    回答要点:冗余部署(主从、主主热备)、健康检查(心跳检测)、故障自动切换(DNS轮询、服务注册中心)、监控告警(Prometheus+Grafana),确保故障时快速恢复。
  • 问题5:缓存雪崩的具体处理方式及效果验证?
    回答要点:分布式缓存设置随机过期时间(TTL=5s+[-3,3]秒偏移),避免集中失效;效果验证通过压力测试(如模拟10万TPS请求,观察缓存失效率是否低于1%)。

7) 【常见坑/雷区】

  • 缓存未加互斥锁导致超卖:多个请求同时查询缓存,扣减库存导致负数,需用分布式锁保证原子性。
  • 数据库事务未考虑最终一致性:订单与库存未用最终一致性,导致库存扣减成功但订单失败,需用事务补偿。
  • 消息队列积压:消费者处理慢于生产者,队列满导致请求阻塞,需增加消费者或优化逻辑。
  • 限流策略不合理:阈值过低拦截正常流量,或过高无法限流,需动态调整(如根据系统容量)。
  • 缓存雪崩未处理:所有缓存同时失效,数据库压力激增,需设置随机过期时间或预热缓存。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1