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

请设计一个支持百万级用户同时值机的航班信息系统,要求99.99%的可用性,请说明核心设计思路和高可用架构。

中国航空集团运行维护岗位难度:中等

答案

1) 【一句话结论】
采用微服务拆分+多区域多活部署+幂等性处理+分布式锁+跨区域数据同步,通过负载均衡和故障自动切换,支撑百万级并发并保证99.99%可用性。

2) 【原理/概念讲解】
高可用架构的核心是“故障隔离+冗余+快速恢复”。故障隔离通过微服务拆分实现,将值机流程拆分为用户认证、航班查询、座位分配、订单生成等独立服务,故障仅影响局部服务;冗余通过多区域多实例部署实现,每个区域部署多套服务实例,避免单区域故障影响全局;快速恢复通过多活架构(核心服务多实例同时运行)和自动故障切换(如主备切换、区域间服务切换)实现,故障时自动切换到备用实例,切换时间控制在秒级(假设网络延迟≤50ms,区域间同步延迟≤100ms,实际切换时间≤1秒)。类比:机场登机系统,每个登机口(服务实例)独立,若某个登机口故障,用户自动去下一个登机口(备用实例),不影响整体;分布式系统中的负载均衡器(如Nginx)类似机场调度中心,将用户请求分发到空闲的登机口。

3) 【对比与适用场景】

架构模式定义特性使用场景注意点
主备架构(Active-Standby)一主多备,主处理请求,备热备主故障时切换,切换有延迟;资源利用率低业务允许短时中断(如非核心,但值机不允许)切换延迟,故障时服务中断
多活架构(Active-Active)多实例同时处理请求,负载均衡实时切换,资源利用率高;故障时部分实例失效高并发、高可用业务(如值机、订票)需要负载均衡和故障检测
微服务+多区域部署服务拆分为微服务,跨区域部署多实例跨区域冗余,网络延迟;故障时区域间服务切换全球用户,区域故障不影响(如国际航班)跨区域同步成本高,需考虑数据一致性

4) 【示例】
伪代码表示值机流程,拆分为微服务,用负载均衡分发,分布式缓存和数据库:

// 用户发起值机请求
用户请求值机(用户ID, 航班号)
  负载均衡器将请求分发到多个值机服务实例
  实例1处理:
    1. 幂等性检查:通过唯一请求ID(如UUID)查询Redis缓存,若已处理则返回成功,避免重复提交
    2. 调用认证微服务(Redis缓存用户信息,减少数据库压力)
    3. 认证通过后,调用航班查询微服务(缓存热点航班信息,如热门航班ID+座位信息)
    4. 座位选择:调用座位分配微服务(Redis分布式锁保证座位唯一性,Lua脚本实现原子性操作)
       Redis Lua脚本:
       if redis.call('get', 'seat_lock:flight_id:user_id') == nil then
         if redis.call('setnx', 'seat_lock:flight_id:user_id', 1, 'ex', 10) == 1 then
           -- 检查座位状态(如剩余座位数>0)
           if redis.call('hget', 'flight_seats:flight_id', 'seat_id') > 0 then
             -- 分配座位:更新座位状态(剩余座位-1)和用户订单(关联座位)
             redis.call('hincrby', 'flight_seats:flight_id', 'seat_id', -1)
             redis.call('hset', 'user_orders:user_id', 'flight_id', flight_id, 'seat_id', seat_id)
             -- 释放锁
             redis.call('del', 'seat_lock:flight_id:user_id')
             return "success"
           else
             redis.call('del', 'seat_lock:flight_id:user_id')
             return "no_seat"
           end
         else
           redis.call('del', 'seat_lock:flight_id:user_id')
           return "lock_failed"
         end
       else
         return "already_processed"
       end
    5. 订单生成:写入分布式事务数据库(Seata保证订单与支付一致性,如订单状态更新、支付扣款)

// 跨区域数据同步(以航班座位信息为例)
区域A的座位分配服务更新座位状态后,通过CDC捕获变更,写入Kafka主题(flight_seats_update)
区域B的座位分配服务订阅该Kafka主题,消费消息并更新本地缓存(如Redis),确保跨区域数据一致性

5) 【面试口播版答案】
面试官您好,针对百万级用户值机系统,核心设计思路是采用微服务拆分+多区域多活部署,结合幂等性处理和分布式锁,确保高并发与高可用。首先将系统拆分为用户认证、航班查询、座位分配、订单生成等微服务,通过负载均衡器(如Nginx+LVS)分发请求到多个实例,提升并发能力;然后部署在多个区域(如北京、上海、广州),每个区域部署多套服务实例,实现故障隔离;数据层采用分布式数据库(如TiDB)和缓存(Redis),提升读写性能;高可用通过多活部署(核心服务如订单同时运行多实例),故障时自动切换,切换时间控制在秒级(假设网络延迟≤50ms,区域间同步延迟≤100ms,实际切换时间≤1秒)。同时,处理值机请求的幂等性,通过唯一请求ID结合Redis缓存避免重复提交;座位分配时使用Redis分布式锁(Lua脚本保证原子性),确保座位唯一性;跨区域数据同步采用CDC捕获变更并通过Kafka同步,保证数据一致性。这样能支撑百万级并发,并保证99.99%的可用性。

6) 【追问清单】

  • 问题1:如何处理跨区域数据同步?
    回答要点:采用CDC(变更数据捕获)捕获本地数据库变更,写入Kafka主题,跨区域服务订阅Kafka消息并更新本地缓存(如Redis),通过事务和补偿机制保证数据一致性。
  • 问题2:如何保证座位分配的原子性?
    回答要点:使用Redis分布式锁(Lua脚本实现加锁、检查座位状态、分配座位、释放锁的原子操作),结合事务管理(如Seata分布式事务)确保座位分配与订单生成的原子性。
  • 问题3:如何应对缓存雪崩?
    回答要点:采用缓存预热(提前加载热点航班、用户信息到缓存)、限流(如RateLimiter限制请求频率)、熔断(如Hystrix熔断故障服务)、降级(如返回默认座位信息),减少缓存失效时的数据库压力。
  • 问题4:如何处理网络分区(如区域间网络故障)?
    回答要点:设计网络分区容错机制,如区域间服务降级(只允许区域内服务交互),故障恢复后自动切换到备用区域,确保系统可用。

7) 【常见坑/雷区】

  • 坑1:采用单体架构,导致扩展性差,无法支撑百万级并发。
    雷区:认为单体架构简单,忽略高并发下的性能瓶颈,无法满足百万级用户值机需求。
  • 坑2:只考虑主备架构,资源利用率低,切换延迟影响用户体验。
    雷区:业务允许短时中断,但值机系统需要秒级响应,主备架构的切换时间可能超过阈值,影响用户体验。
  • 坑3:缓存未做预热和限流,导致缓存雪崩,系统崩溃。
    雷区:未考虑热点数据,缓存全量失效时,大量请求直接访问数据库,导致数据库压力过大,系统不可用。
  • 坑4:分布式事务处理不当,导致数据不一致(如订单与支付)。
    雷区:使用本地事务或简单事务,未考虑跨服务事务,导致数据不一致问题,如订单已生成但支付未完成。
  • 坑5:高可用架构未考虑网络分区,区域间网络故障时系统不可用。
    雷区:未设计网络分区容错,区域间服务完全依赖,故障时整个系统崩溃,无法满足高可用要求。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1