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

设计一个高并发的支付系统,要求支持秒级响应,并保证交易一致性(订单-库存-支付)。请说明系统架构、关键技术选型及容灾方案。

Tencent技术运营难度:困难

答案

1) 【一句话结论】

采用微服务拆分订单、库存、支付模块,通过消息队列解耦,结合最终一致性(Saga模式)保证交易一致性,利用缓存+分布式锁优化性能,数据库分库分表提升吞吐,并设计多级容灾方案(主备切换、数据同步)。

2) 【原理/概念讲解】

老师:设计高并发支付系统,核心是解耦与一致性。首先,订单、库存、支付属于不同业务逻辑,需拆分为独立微服务(如订单服务、库存服务、支付服务),避免单点故障。

  • 分布式事务挑战:跨服务调用导致事务边界模糊,传统两阶段提交(2PC)阻塞严重,不适合高并发。
  • 最终一致性方案:允许短暂不一致,通过Saga模式(补偿机制)恢复。例如,订单创建→库存扣减→支付→库存释放,若某步失败,后续步骤触发补偿(如支付失败则库存加回)。
  • 消息队列作用:异步解耦,削峰填谷(如支付高峰时消息队列缓冲请求)。
  • 缓存策略:
    • 订单:读多写少,用Redis缓存(减少数据库压力)。
    • 库存:读多写少,加Redis分布式锁(SETNX+超时)保证扣减原子性。
  • 数据库分库分表:水平拆分(如按订单ID分库),提升读写吞吐,但需分布式事务方案(如Seata)处理跨库事务。

3) 【对比与适用场景】

方案定义特性使用场景注意点
2PC两阶段提交强一致性,阻塞调用需强一致性(如核心金融交易)阻塞问题,单点故障风险
Saga最终一致性+补偿非阻塞,可恢复高并发,允许短暂不一致补偿逻辑复杂,可能死锁
TCC尝试-确认-取消最终一致性,低阻塞需原子性(如库存扣减)业务逻辑复杂,需幂等性保证

(注:高并发场景优先选Saga/TCC,避免2PC阻塞。库存扣减用TCC模式:Try扣减库存,Confirm释放,Cancel回滚。)

4) 【示例】

用户下单流程(伪代码):

  1. 订单服务:

    def create_order(user_id, product_id, amount):
        order_no = generate_order_no()
        # 分布式锁保证库存扣减原子性
        lock = redis.setnx(f"stock_lock_{product_id}", user_id, ex=10)  # 超时10秒
        if lock:
            inventory = get_inventory_from_cache(product_id)  # 从缓存查库存
            if inventory >= amount:
                set_inventory(product_id, inventory - amount)  # 扣减库存
                # 发送支付消息
                send_message("payment_queue", order_no, amount)
                save_order(order_no, user_id, product_id, amount, "待支付")
                return order_no
            else:
                release_lock(f"stock_lock_{product_id}", user_id)
                return "库存不足"
        else:
            return "并发冲突"
    
  2. 支付服务:

    def process_payment(order_no):
        order = get_order_from_cache(order_no)  # 从缓存查订单
        if order.status == "待支付":
            payment_result = call_payment_gateway(order.amount)  # 调用支付网关
            if payment_result == "success":
                update_order(order_no, "已支付")
                # 发送库存补偿消息
                send_message("inventory_queue", order_no, order.product_id)
            else:
                update_order(order_no, "支付失败")
    
  3. 库存服务(补偿逻辑):

    def release_inventory(order_no):
        order = get_order_from_cache(order_no)
        if order.status == "支付失败":
            add_inventory(order.product_id, order.amount)  # 补偿加回库存
    

5) 【面试口播版答案】

(约80秒)
面试官您好,设计高并发支付系统,核心思路是微服务拆分+消息队列解耦+最终一致性保障。具体来说:
订单服务创建订单后,调用库存服务扣减库存(Redis分布式锁保证原子性),成功后发送支付消息;支付服务消费消息后调用支付网关,成功则更新订单并通知库存释放库存。关键技术包括Redis分布式锁(解决并发库存冲突)、消息队列(削峰填谷)、缓存(提升读性能),数据库分库分表提升吞吐。容灾方面,主库故障时自动切换备库,数据通过日志同步,消息队列持久化确保不丢失。这样既能保证秒级响应,又能保证订单-库存-支付的一致性。

6) 【追问清单】

  1. 问:分布式事务具体怎么实现?比如Saga模式的具体补偿流程?
    回答:Saga模式通过消息队列传递补偿指令,每个步骤失败后触发补偿(如支付失败则库存加回,订单状态回滚)。

  2. 问:库存扣减的原子性如何保证?如果分布式锁超时怎么办?
    回答:用Redis SETNX加超时时间,超时后释放锁并通知重试;若超时导致库存扣减失败,补偿机制会回滚。

  3. 问:消息队列的可靠性如何保障?比如消息丢失或重复消费?
    回答:消息队列持久化存储(如RocketMQ事务消息),消费端幂等处理(如根据订单号判断是否重复消费)。

  4. 问:缓存雪崩如何处理?比如库存缓存全过期?
    回答:设置合理缓存过期时间,并采用热点数据预热;若缓存雪崩,本地缓存+数据库双写保证可用性。

  5. 问:数据库分库分表后,分布式事务如何处理?比如Seata的实现?
    回答:使用Seata的AT模式,将本地事务和全局事务结合,保证跨服务事务的原子性(如订单创建与库存扣减)。

7) 【常见坑/雷区】

  1. 忽略库存扣减原子性:只做订单扣减导致库存超卖(需分布式锁保证)。
  2. 消息队列未处理幂等性:重复消费导致重复扣减库存。
  3. 分布式锁未加超时:死锁风险(如锁持有时间过长)。
  4. 最终一致性补偿逻辑复杂:可能造成循环调用或死锁(需设计幂等补偿)。
  5. 数据库分库分表后事务处理不当:导致部分提交(需分布式事务方案)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1