1) 【一句话结论】在移动端高并发场景(如双11登录),通过负载均衡分散请求压力、缓存减少数据库访问、分库分表水平扩展数据库、消息队列解耦异步任务,多技术组合提升系统吞吐量与稳定性。
2) 【原理/概念讲解】
- 负载均衡:通过Nginx等工具将用户请求分发到多个后端服务实例,避免单点过载。类比:交通枢纽(如高铁站)根据车次和站台分配乘客,确保每个站台压力均衡。
- 缓存:使用Redis等内存数据库存储热点数据(如用户登录态、商品信息),减少对数据库的读压力。类比:超市货架(缓存)存放热销商品,顾客直接取货,无需去仓库(数据库)拿,提升速度。
- 分库分表:水平拆分数据库(分库按用户ID范围,分表按时间或业务类型),垂直拆分(将大表拆分为多个小表,如用户表拆分为用户基础表和用户行为表)。类比:大型超市将商品按区域(分库)和类别(分表)摆放,方便顾客查找,减少找货时间。
- 消息队列:通过Kafka等中间件,将高并发请求中的异步任务(如登录后推送消息、数据同步)解耦,生产者发送消息到队列,消费者异步处理,避免阻塞主流程。类比:快递分拣中心,寄件人(生产者)把包裹放入分拣口(队列),分拣员(消费者)按顺序处理,不影响寄件速度。
3) 【对比与适用场景】
| 技术手段 | 定义 | 特性 | 使用场景 | 注意点 |
|---|
| 负载均衡 | 将请求分发到多个后端服务实例 | 轮询、权重、会话粘性等算法 | 高并发请求入口 | 需考虑会话一致性,避免粘性导致单点压力 |
| 缓存 | 存储热点数据,减少数据库访问 | 快速读写,支持过期、淘汰策略 | 热点数据(如用户信息、商品详情) | 需设置合理过期时间,避免数据不一致 |
| 分库分表 | 水平/垂直拆分数据库,扩展容量 | 水平扩展(分库分表),垂直扩展(拆分表) | 数据量大的核心表(如用户表、订单表) | 跨表查询复杂,需优化SQL |
| 消息队列 | 解耦异步任务,缓冲流量 | 生产者-消费者模型,持久化、事务 | 异步任务(如推送、通知、数据同步) | 需考虑消息积压和延迟,监控队列状态 |
4) 【示例】
假设双11登录场景:
- 用户发起登录请求,负载均衡(Nginx)将请求分发到多个登录服务实例。
- 登录服务先检查Redis缓存(用户登录态),若存在则直接返回成功,否则查询数据库(分库分表后的用户表),将登录态存入Redis(设置过期时间)。
- 登录成功后,将“推送消息”任务发送到Kafka队列(生产者),消费者(推送服务)异步处理,将登录成功通知推送给用户。
伪代码(请求示例):
POST /login
{
"phone": "13800138000",
"password": "123456"
}
负载均衡分发后,登录服务查询Redis(缓存),若缓存命中,返回200;否则查询数据库(分库分表),更新Redis并返回。
5) 【面试口播版答案】
“我参与过一个双11移动端登录项目,遇到高并发登录请求。首先,通过Nginx做负载均衡,将请求分发到多个登录服务实例,避免单点过载。然后,用Redis缓存用户登录态,减少数据库查询压力,缓存未命中时再查数据库。数据库方面,用户表按用户ID分库分表,水平扩展容量。登录后,将推送消息任务放入Kafka队列,异步处理,避免阻塞主流程。通过这些技术组合,系统在双11期间成功支撑了百万级并发登录,响应时间控制在1秒内。”
6) 【追问清单】
- 问:负载均衡的算法选择?
答:主要用轮询和权重,根据实例健康状态调整,比如轮询保证每个实例压力均衡,权重根据实例性能调整。
- 问:缓存雪崩怎么办?
答:设置合理的过期时间(如TTL),或者用分布式锁控制并发写入,避免大量缓存失效时同时查询数据库。
- 问:分库分表后,跨表查询如何处理?
答:通过分片键(如用户ID)关联表,或者将相关表放在同一分库,或者优化SQL,减少跨库操作。
- 问:消息队列的延迟消息如何实现?
答:Kafka支持延迟发送,通过时间戳和延迟时间设置,生产者发送后,消费者在指定时间处理。
- 问:系统监控方面做了什么?
答:监控负载均衡的请求分发率、缓存命中率、数据库QPS、消息队列的积压数,通过Prometheus和Grafana实时监控,及时调整资源。
7) 【常见坑/雷区】
- 负载均衡未考虑会话粘性,导致用户登录后切换实例,需要重新登录。
- 缓存未设置过期策略,导致缓存数据过期后,大量请求查询数据库,引发雪崩。
- 分库分表设计不合理,比如按时间分表导致查询时需要扫描大量表,影响性能。
- 消息队列积压导致延迟,未设置消息积压处理机制,影响业务流程。
- 未考虑容灾,比如数据库分库分表后,某个分库故障,未做数据备份和切换方案。