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

请设计一个高并发的游戏交易系统(如商城购买道具),需要满足以下需求:1)支持每秒数千笔交易;2)保证交易原子性(防止超卖);3)提供实时交易状态查询;4)考虑容错和恢复机制。请详细说明系统架构、核心模块设计、关键技术选型(如数据库、缓存、消息队列)以及性能优化点。

游卡Golang开发难度:困难

答案

1) 【一句话结论】
系统采用微服务架构,核心交易服务通过Redis Lua脚本实现库存原子扣减,跨服务操作用Saga模式保证最终一致性,数据库(MySQL)存储核心数据,Redis缓存加速查询,Kafka记录交易日志实现容错恢复,满足高并发、原子性、实时查询及容错需求。

2) 【原理/概念讲解】

  • 超卖问题:游戏商城中,若多个请求同时扣减库存,可能导致库存被超卖(如库存100,同时有10个请求各扣10,实际库存不足)。解决核心是“原子性”,即库存扣减和余额扣减必须同时成功或同时失败,类比银行转账,不能先扣款后确认,否则资金不安全。
  • 原子性:单服务内(如扣减库存+更新订单)用Redis Lua脚本保证原子性;跨服务(如扣减库存和更新订单属于不同服务)用Saga模式,通过补偿机制确保最终一致性。
  • 实时交易状态查询:用户需要立即看到购买结果,通过Redis缓存交易状态(数据库更新后异步刷新缓存),查询延迟低。
  • 容错与恢复:系统故障时(如服务宕机),通过消息队列记录每一步操作,服务恢复后重试未完成的交易,避免数据丢失。

3) 【对比与适用场景】

技术选型定义/特性使用场景注意点
MySQL关系型数据库,支持ACID事务核心交易数据持久化(用户余额、订单表)高并发下需分库分表,事务锁竞争;结合Redis读写分离加速查询
Redis内存数据库,支持原子操作(Lua脚本)库存扣减、实时状态缓存读多写少场景,需持久化(RDB/AOF);Lua脚本高并发下性能影响(需预计算)
Kafka分布式消息队列交易日志、异步通知、容错重试需保证消息不丢失(ACK=all),消息堆积时需限流
Saga模式跨服务分布式事务,通过补偿事务保证最终一致性跨服务扣减库存和更新订单需设计状态机,失败时触发补偿,可能引入延迟
Seata AT模式分布式事务中间件,对业务代码无侵入跨服务扣减库存和更新订单适用于高并发,但需考虑数据库支持,锁竞争风险
缓存雪崩防护热点key随机化TTL + 限流熔断防止Redis缓存大量过期导致查询压力激增需监控热点key,动态调整TTL

4) 【示例】
购买道具流程(伪代码):

  1. 客户端请求:POST /api/purchase,参数:userId, itemId, amount。
  2. API网关路由到交易服务。
  3. 交易服务:
    a. 验证用户余额(Redis查询,若余额不足返回错误)。
    b. 扣减库存(Redis Lua脚本:if (库存 >= amount) then 库存 = 库存 - amount end,返回结果)。
    c. 更新订单(MySQL事务:插入订单表,包含userId, itemId, amount, status=“待发货”)。
    d. 发送交易日志到Kafka(主题:transaction-log,消息体:{userId, itemId, amount, status=“扣减成功”})。
  4. 实时查询:用户查询订单状态,API网关查询Redis缓存(若缓存未命中,查询MySQL并更新Redis,设置5分钟TTL)。
  5. 容错恢复:若扣减库存失败(Lua脚本返回库存不足),则发送失败日志到Kafka,服务重启后重试扣减逻辑(指数退避,如1秒、2秒、3秒,最多3次)。

5) 【面试口播版答案】
面试官您好,针对高并发游戏交易系统,我的设计聚焦于“原子性”与“容错恢复”。首先,核心交易服务通过Redis Lua脚本实现库存和余额的原子扣减,避免超卖;跨服务操作(如扣减库存和更新订单)采用Saga模式,通过补偿事务确保最终一致性。数据库层面,用户余额、订单表存储在MySQL,分库分表提升并发,Redis作为读写分离缓存,加速查询。实时状态查询通过Redis缓存+数据库双写,延迟低。容错方面,交易日志写入Kafka,支持重试,比如扣减失败时,消息队列重试,指数退避避免循环。性能优化上,消息队列异步处理通知,Redis Lua脚本避免锁竞争,还考虑了缓存预热和雪崩防护(如热点key随机化TTL)。

6) 【追问清单】

  • 幂等性:用请求ID+Redis SETNX(单次设置,失败则返回错误)或订单表唯一索引,确保重复请求不重复扣减。
  • 分布式事务补偿延迟:Saga模式失败时,补偿事务可能引入延迟,需设计状态机,优先处理关键步骤,避免连锁失败。
  • 缓存一致性:数据库更新订单后,异步调用Redis Lua脚本更新缓存,设置5分钟TTL,并添加异步刷新的延迟重试(如1秒后重试,最多3次)。
  • Kafka堆积限流:生产者端设置批量发送(如16KB批次),消费者端设置最大并发数(如10个消费者),避免消息堆积导致系统过载。
  • 消息丢失处理:Kafka采用ACK=all,确保消息不丢失,服务重启后从最新偏移量消费,避免重复处理。

7) 【常见坑/雷区】

  • 跨服务事务未用Saga/Seata,导致超卖风险未覆盖。
  • 缓存未设置TTL,查询脏数据。
  • 消息队列未配置ACK,交易日志丢失。
  • 分布式事务选型错误,如两阶段提交,高并发下阻塞。
  • 补偿逻辑缺失,扣减失败后库存未回滚,数据不一致。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1