
1) 【一句话结论】采用分层微服务架构,通过负载均衡分发请求、WebSocket实现实时通信、分布式数据库与缓存分摊压力,并部署监控告警体系,确保百万级并发下的低延迟与高稳定性。
2) 【原理/概念讲解】同学们,设计百万级并发系统核心是“分而治之”。系统架构分层:前端展示层(如React/Vue)负责用户交互,应用层拆分为用户服务、题库服务、考试服务、计分服务等微服务,数据层用分布式数据库(如TiDB)和Redis缓存分摊压力。负载均衡是关键,用Nginx作为四层负载均衡器,将请求分发到多台应用服务器,避免单点故障。实时通信方面,考试需实时更新题目、计时,用WebSocket(持久连接)比轮询更高效,服务器可主动推送消息。监控策略上,用Prometheus收集系统指标(CPU、内存、QPS),用Grafana可视化,同时用ELK分析日志,及时发现异常。
3) 【对比与适用场景】
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Nginx | 开源反向代理服务器 | 高性能,支持轮询、权重、IP哈希等算法 | Web应用、API网关 | 需配置会话粘性(Session Sticky),如Nginx的ip_hash或session_sticky模块 |
| HAProxy | 高性能负载均衡器 | 支持TCP/HTTP/HTTPS,支持会话保持 | 高并发Web服务 | 配置复杂,需熟悉命令行,适合复杂负载场景 |
| 缓存策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Redis | 分布式内存数据库 | 高速读写,支持数据持久化 | 热点数据缓存(如考试规则、题目) | 需考虑缓存雪崩(预热+互斥锁)、缓存穿透(布隆过滤器+空值缓存) |
| Memcached | 内存缓存 | 适用于简单键值存储 | 瞬态数据缓存 | 缓存失效机制需严格设计,避免内存泄漏 |
| 实时通信协议 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| WebSocket | 持久连接,双向通信 | 低延迟,支持主动推送 | 考试倒计时、题目更新等实时交互 | 需实现心跳机制(定期ping pong)和断线重连逻辑 |
| Server-Sent Events | 单向推送 | 仅支持服务器向客户端推送 | 成绩发布等单向通知 | 不支持双向交互,不适合考试实时更新 |
4) 【示例】
前端请求考试(GET /exam/start?examId=123):
GET /exam/start?examId=123 HTTP/1.1
Host: exam-system.com
后端处理:
ip_hash将请求分发到应用服务器A(确保会话粘性);exam_id=123的题目表);{"type":"timer","time":30})。伪代码(后端WebSocket处理):
def handle_websocket_connection(client):
while True:
try:
# 心跳检测
if not client.is_heartbeating():
client.send("ping")
client.heart_beat()
# 接收答题消息
message = client.receive()
process_answer(message)
# 推送实时数据
client.send({"type": "timer", "time": current_time})
except ConnectionClosedError:
break # 连接断开,触发重连
5) 【面试口播版答案】
面试官您好,针对百万级用户同时在线的在线考试系统,我的设计思路是采用分层微服务架构,结合负载均衡、WebSocket实时通信和监控体系,确保低延迟与稳定性。首先,系统架构分层:前端展示层负责用户交互,应用层拆分为用户服务、题库服务、考试服务、计分服务等微服务,数据层用分布式数据库(如TiDB)和Redis缓存分摊压力。然后,负载均衡用Nginx作为四层负载均衡器,通过ip_hash实现会话粘性,避免用户状态不一致。实时通信方面,考试过程中需要实时更新题目、计时,所以用WebSocket实现持久连接,服务器主动推送消息,比轮询更高效。监控策略上,用Prometheus收集系统指标(CPU、内存、QPS),用Grafana可视化,同时用ELK分析日志,及时发现异常。这样整体架构能支撑百万级并发,保证低延迟和高稳定性。
6) 【追问清单】
exam_1、exam_2),按用户ID分表(如user_1、user_2),确保读写分离,提升查询效率。7) 【常见坑/雷区】