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

设计一个支持百万级用户同时在线的银行核心交易系统,要求高可用、低延迟,请描述系统架构、关键技术选型及如何保证数据一致性。

招商银行职能类岗位难度:困难

答案

1) 【一句话结论】
采用微服务架构结合服务治理、缓存、数据库分库分表、消息队列及Saga模式分布式事务,通过水平扩展、负载均衡、异步处理实现百万级用户高可用、低延迟,并保障数据一致性。

2) 【原理/概念讲解】
老师会解释系统架构分层:前端(用户请求入口)、网关(路由、限流、鉴权)、服务层(微服务拆分,如账户服务、交易服务、订单服务,独立部署,类比企业部门分工,财务部、交易部各司其职,扩展时只需增人,不影响其他部门)、数据层(Redis集群缓存热点数据,减少数据库压力;数据库通过分库分表(如ShardingSphere)水平扩展,主从复制实现读写分离(主写从读,提升读性能)。关键技术:

  • 服务治理:Nacos注册中心实现服务注册发现(服务实例动态注册,负载均衡器根据实例状态分发请求);Sentinel实现熔断(故障服务实例被隔离,避免级联故障)和限流(控制请求速率,防止服务过载);故障隔离(熔断机制确保故障服务不影响其他服务)。
  • 缓存策略:写时刷新(Write-Through):数据库更新后同步Redis(如账户余额扣减后,立即更新Redis缓存);读时回源(Read-Through):缓存未命中时查询数据库(如查询账户余额,若缓存为空则从数据库读取并回填缓存);缓存预热(初始化时预加载热点数据,避免首次访问延迟)。
  • 数据一致性:Saga模式(最终一致性):将转账事务拆分为“扣款”和“转账”两个本地事务,通过消息队列(Kafka)传递状态;若订单服务失败,触发补偿事务(幂等性:检查账户状态或使用唯一标识,避免重复回滚)。

3) 【对比与适用场景】

方案定义特性使用场景注意点
两阶段提交(2PC)强一致性,协调者与参与者两阶段提交阻塞式,协调者故障导致所有参与者阻塞需强一致性场景(如金融核心交易,但实际协调者故障风险高)阻塞问题,性能低,协调者故障时系统不可用
Saga模式最终一致性,通过消息队列协调本地事务异步,非阻塞,容错性好银行转账、订单支付等业务,允许短暂不一致需补偿机制,极端网络分区时可能不一致
TCC模式补偿模式,预检查、执行、回滚预检查保证业务正确性,回滚快速需预检查,如库存扣减预检查可能不充分,导致业务错误

4) 【示例】
用户发起转账请求(金额100元,从账户A到账户B):

  1. 前端发送请求到网关(Nginx)。
  2. 网关路由到转账服务(微服务),Sentinel限流检查请求速率。
  3. 转账服务检查Redis缓存:account_A_balance(若缓存未命中,查询数据库)。
  4. 若余额足够,执行数据库事务:UPDATE accounts SET balance = balance - 100 WHERE id='A'(写时刷新Redis)。
  5. 发送Kafka消息:topic=transfer, value={"from":"A","to":"B","amount":100}。
  6. 订单服务消费Kafka消息,更新账户B余额(数据库事务)。
  7. 若订单服务失败,发送补偿消息:topic=compensation, value={"from":"A","to":"B","amount":100}。
  8. 补偿服务消费补偿消息,执行回滚:UPDATE accounts SET balance = balance + 100 WHERE id='A'(幂等性检查:若账户A余额已恢复,则跳过)。

伪代码(简化):

// 用户请求
{
  "from_account": "A",
  "to_account": "B",
  "amount": 100
}

// 转账服务处理
1. 检查Redis缓存:account_A_balance
2. 若缓存为空,查询数据库:SELECT balance FROM accounts WHERE id='A'
3. 若余额 >= 100,执行数据库事务:UPDATE accounts SET balance = balance - 100 WHERE id='A'
4. 发送Kafka消息:topic=transfer, value={"from":"A","to":"B","amount":100}
5. 等待订单服务处理(异步)

// 订单服务消费Kafka消息
1. 消费消息:{"from":"A","to":"B","amount":100}
2. 执行数据库事务:UPDATE accounts SET balance = balance + 100 WHERE id='B'
3. 若失败,发送补偿消息:topic=compensation, value={"from":"A","to":"B","amount":100}
4. 补偿服务消费补偿消息,执行回滚:UPDATE accounts SET balance = balance + 100 WHERE id='A'

5) 【面试口播版答案】
“面试官您好,针对百万级用户高可用、低延迟的银行核心交易系统,我设计的架构核心是微服务+服务治理+缓存+数据库分库。系统分层为前端、网关、服务层、数据层。前端接收用户请求,网关负责路由、限流和鉴权,服务层拆分为账户、交易、订单等微服务,通过Nacos注册中心实现服务注册发现,Sentinel实现熔断和限流,故障实例被隔离。数据层采用Redis集群缓存热点数据(如用户账户信息),数据库通过分库分表(ShardingSphere)水平扩展,主从复制实现读写分离。为保障低延迟,交易逻辑尽量在缓存中处理,数据库操作通过Kafka异步处理,避免阻塞。数据一致性方面,采用Saga模式,将转账拆分为扣款和转账两个本地事务,通过消息队列协调,若订单服务失败则触发补偿,补偿事务检查账户状态确保幂等性,最终保证数据一致。这样,系统通过水平扩展、负载均衡、缓存和异步处理,实现高可用和低延迟,同时保障数据一致性。”

6) 【追问清单】

  • 问:系统如何处理服务故障?比如某个微服务实例宕机?
    回答要点:通过Nacos注册中心剔除故障实例,负载均衡器自动路由请求到其他正常实例;Redis集群主从复制,主节点故障时自动切换从节点;数据库分库分表,某个分片故障时,请求路由到其他分片。
  • 问:缓存雪崩或击穿如何解决?
    回答要点:缓存雪崩用随机过期时间;缓存击穿用Redis的SETNX互斥锁,避免热点数据同时请求数据库。
  • 问:分布式事务的具体实现?比如Saga模式如何保证最终一致?
    回答要点:Saga模式将事务拆分为多个本地事务,通过消息队列传递状态,每个本地事务成功则发送确认消息,失败则发送补偿消息,最终通过补偿机制确保数据一致。
  • 问:高可用具体措施?比如数据库的冗余?
    回答要点:数据库采用主从复制(主写从读),主节点故障时从节点切换为主节点;服务层多实例部署,负载均衡分发请求;网关层有备用节点,避免单点故障。
  • 问:系统扩展性如何?比如用户量增长时如何扩展?
    回答要点:微服务独立部署,根据流量扩展特定服务(如交易服务);数据库分库分表,增加分片数量;缓存集群扩容,增加Redis节点。

7) 【常见坑/雷区】

  • 雷区1:只说微服务而不提服务治理(注册发现、熔断、限流),导致系统高可用容错性描述不完整。
  • 雷区2:忽略缓存与数据库的一致性策略(写时刷新、读时回源),以及补偿事务的幂等性,导致数据不一致风险。
  • 雷区3:对数据一致性描述过于绝对(“必然保证”),忽略了Saga模式的最终一致性及极端情况风险。
  • 雷区4:模板化类比(如企业部门分工),以及通用性描述(如“高效/赋能”),缺乏具体技术细节支撑。
  • 雷区5:B部分例子未考虑超时等边界条件,导致信息堆砌,结构不清晰。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1