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

设计一个支持百万级用户同时在线的在线考试系统,要求低延迟(秒级响应),高可用(99.9%以上),并处理考试过程中的实时监控(如答题时间、提交状态)。请从架构、数据库、缓存、消息队列等方面说明系统设计思路。

深圳大学中国龙工难度:困难

答案

1) 【一句话结论】采用微服务架构+分布式组件设计,通过负载均衡分散请求、缓存加速热点数据、消息队列解耦实时监控、数据库分库分表保障高并发与高可用,实现百万级用户同时在线的秒级响应与99.9%以上高可用。

2) 【原理/概念讲解】

  • 微服务架构:将系统拆分为用户服务(管理用户登录/权限)、考试服务(处理考试流程)、监控服务(实时监控答题状态)等独立微服务,每个服务独立部署、扩展,提升系统灵活性与可维护性(类比:把大公司拆成多个子公司,各自负责不同业务,便于单独调整)。
  • 负载均衡:前端部署Nginx/LVS,将用户请求分发到多台应用服务器集群,避免单点故障,同时分散请求压力(类比:超市收银台设置多个窗口,避免排队拥堵)。
  • 缓存(Redis):存储用户状态(如剩余答题时间)、热点考试题目等高频访问数据,通过内存读写实现秒级响应,同时支持数据持久化(RDB/AOF),避免缓存失效导致数据丢失(类比:超市货架放畅销商品,快速拿取,同时货架有库存记录)。
  • 消息队列(Kafka):解耦实时监控与业务流程,考试服务更新答题时间后,通过Kafka发送消息,监控服务消费消息更新界面,避免业务与监控直接耦合(类比:快递中转站,发货方和收货方不直接联系,通过中转站传递包裹)。
  • 数据库(分库分表):关系型数据库(如MySQL)存储结构化数据(用户信息、考试记录),通过分库(按用户ID哈希)分表(按考试ID时间范围)水平扩展,提升读写性能;NoSQL(如MongoDB)存储非结构化数据(用户答题内容),适配灵活的数据结构(类比:图书馆按书籍分类分库,按作者分表,方便查找)。

3) 【对比与适用场景】

组件定义/特性使用场景注意点
缓存(Redis)支持高并发读写、数据持久化、事务、发布订阅热点数据(用户状态、考试题目)需设置过期时间,避免缓存穿透
缓存(Memcached)简单缓存,不支持持久化、事务简单缓存(如临时数据)数据易丢失,适合非关键场景
消息队列(Kafka)高吞吐、持久化、分布式、多消费者实时监控、日志、解耦服务需考虑消息堆积与消费延迟
消息队列(RabbitMQ)支持多种消息模型(队列/主题)、路由复杂路由场景(如多服务消费)配置复杂,适合业务逻辑复杂场景
数据库(MySQL)关系型,事务一致性强结构化数据(用户信息、考试记录)需分库分表,避免单表性能瓶颈
数据库(MongoDB)NoSQL,灵活数据结构非结构化数据(答题内容、日志)无事务支持,需保证数据一致性

4) 【示例】

  • 架构流程:用户请求通过Nginx负载均衡分发到应用服务器集群,应用服务器调用考试服务(微服务),考试服务从Redis获取用户剩余时间,更新后通过Kafka发送“答题时间变更”消息,监控服务消费消息并更新实时监控界面。
  • 数据库分库分表示例:
    • 用户表(user_table)按用户ID哈希分库(如库1存储ID 1-100万,库2存储100万+),避免单库数据量过大。
    • 考试记录表(exam_record)按考试ID时间范围分表(如表1存储考试ID 1-1000,表2存储1001-2000),提升查询性能。
  • 伪代码(考试服务更新答题时间):
    # 考试服务更新答题时间
    def update_answer_time(user_id, exam_id, new_time):
        # 从Redis获取用户状态(剩余时间)
        user_state = redis.get(f"user_{user_id}_state")
        # 更新Redis用户状态
        redis.set(f"user_{user_id}_state", new_time)
        # 通过Kafka发送答题时间变更消息
        kafka_producer.send("exam_answer_time_topic", 
                            value={"user_id": user_id, "exam_id": exam_id, "new_time": new_time})
    

5) 【面试口播版答案】
面试官您好,针对百万级用户同时在线的在线考试系统,我的设计思路是采用微服务架构+分布式组件,核心是分层设计:前端层用负载均衡(Nginx)分发请求到多台应用服务器,应用层拆分为用户、考试、监控等微服务,数据层通过缓存(Redis)加速热点数据,消息队列(Kafka)解耦实时监控,数据库分库分表保障高并发。具体来说,负载均衡分发请求后,考试服务从Redis获取用户剩余时间,更新后通过Kafka发送答题时间变更,监控服务消费消息更新界面;数据库通过分库(用户表按ID哈希)分表(考试记录按考试ID时间范围),实现99.9%高可用和秒级响应。

6) 【追问清单】

  • 问题1:高并发下缓存雪崩如何处理?
    回答要点:设置缓存过期时间随机化(如1.5-2.5秒),避免集中过期;配置Redis集群和读写分离,提升缓存可用性。
  • 问题2:数据库分库分表的具体策略?
    回答要点:用户表按用户ID哈希分库,考试记录表按考试ID时间范围分表,使用ShardingSphere实现,确保数据均匀分布。
  • 问题3:消息队列的可靠性保证?
    回答要点:消息持久化存储,消费端确认机制(ACK),重试和死信队列处理失败消息,避免消息丢失。
  • 问题4:实时监控的指标设计?
    回答要点:监控答题时间、提交状态、系统延迟等关键指标,通过Prometheus+Grafana展示,及时发现系统问题。
  • 问题5:微服务间通信的容错机制?
    回答要点:服务间调用使用熔断、降级、重试机制,避免单服务宕机影响整体系统。

7) 【常见坑/雷区】

  • 坑1:直接用单机数据库,未分库分表,导致高并发下性能瓶颈。
  • 坑2:缓存未设置过期策略,导致数据不一致或缓存穿透(如用户答题时间未更新,缓存仍显示旧数据)。
  • 坑3:消息队列未考虑重试和死信队列,导致消息丢失(如监控服务消费失败,答题时间未更新)。
  • 坑4:实时监控未设计关键指标,无法及时发现系统延迟或故障(如未监控答题时间更新延迟,导致用户体验下降)。
  • 坑5:微服务间通信未考虑容错,如服务宕机导致请求失败,未做熔断处理。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1