
设计百万级用户登录系统,核心是通过分布式架构(负载均衡、缓存、数据库分片)、安全机制(密码加盐哈希、token防重放)、容错保障(限流、熔断、异步解耦),确保高并发下低延迟、数据可靠且安全。
从请求分发、数据存储、流程解耦、安全控制、容错保障五个维度讲解关键要素:
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 负载均衡 | 分发请求到多个服务器 | 轮询/IP哈希/权重 | 高并发请求 | 需考虑会话粘性(如Cookie) |
| 缓存(Redis) | 存储高频数据 | 高速、持久化 | 登录状态、用户信息 | 需设置过期时间,避免不一致 |
| 数据库分片 | 按键哈希/范围切分数据 | 分散数据量,提升读性能 | 用户量巨大(百万级) | 分片键变更时需考虑数据迁移 |
| 消息队列 | 异步处理业务 | 解耦、削峰 | 登录通知、日志 | 需保证消息幂等性 |
| 限流(令牌桶) | 控制请求速率 | 令牌生成速率决定QPS | 防止流量过大 | 参数需动态调整(如负载变化) |
| 熔断 | 故障时拒绝请求 | 快速失败 | 服务故障时保护系统 | 阈值需合理设置(如错误率) |
用户请求:GET /login?user=xxx&pwd=xxx
user:xxx:login:token),有则直接返回token。user:xxx:login:token,ttl: 3600),并异步发送登录通知(Kafka消息:user:xxx, action:login_success)。def login(user_id, password):
token = get_from_cache(f"user:{user_id}:login:token")
if token:
return {"status": "success", "token": token}
user = query_db(user_id) # 分片数据库查询,主库
if user and check_password(user.password_hash, password):
token = generate_jwt(user_id, expires=3600) # 带过期时间
set_cache(f"user:{user_id}:login:token", token, ttl=3600)
send_to_kafka("login_success", {"user_id": user_id})
return {"status": "success", "token": token}
return {"status": "fail", "message": "invalid credentials"}
``
### 5) 【面试口播版答案】(约90秒)
“面试官您好,设计百万级用户登录系统,核心是通过分布式架构平衡性能与安全。首先,负载均衡(Nginx轮询)分发请求到应用集群,避免单点过载。然后,缓存层(Redis)存储高频登录状态,高频请求直接从缓存获取token,降低数据库压力。当缓存未命中时,查询分片数据库(主库),验证密码(BCrypt哈希比对)。验证成功后,生成带签名的token(含用户ID、过期时间),存入缓存并设置过期时间。登录成功后,通过消息队列(Kafka)异步发送登录通知,解耦业务。同时,采用令牌桶限流控制请求速率,熔断防止故障扩散。比如,缓存击穿时,设置热点key的默认值(如“用户不存在”),或用Redis锁保证单次查询数据库。数据库分片按用户ID哈希到不同库,读写分离提升读性能。这样,高并发下能保持低延迟,且数据可靠安全。”
### 6) 【追问清单】
- **问题1:如何处理缓存击穿?**
回答要点:设置热点key的默认值(如“用户不存在”),或预加载热点数据(定时任务),或用Redis锁(SETNX加过期时间)保证单次查询。
- **问题2:数据库分片如何实现?**
回答要点:按用户ID哈希到不同分片,主从复制提升读性能,分片键选择需考虑业务扩展性(如用户ID范围变化时,迁移数据需分阶段,避免影响业务)。
- **问题3:限流策略具体怎么实现?**
回答要点:令牌桶算法,每秒生成固定数目的令牌,请求消耗令牌,超过则拒绝;参数动态调整(如根据系统负载,高负载时降低令牌生成速率)。
- **问题4:密码存储如何保证安全?**
回答要点:使用加盐哈希(如BCrypt),避免明文存储,防止暴力破解。
- **问题5:token如何防重放攻击?**
回答要点:token中包含时间戳或nonce,验证时检查是否过期或重复。
### 7) 【常见坑/雷区】
- 坑1:密码未加盐哈希,导致安全风险(暴力破解)。
- 坑2:分片键选择不当(如按时间分片),导致数据迁移困难,影响业务扩展。
- 坑3:缓存击穿处理不当,导致热点key失效时大量请求落库,引发服务雪崩。
- 坑4:限流参数设置过松,无法有效控制流量,导致系统过载。
- 坑5:token无防重放机制,导致重复登录或恶意攻击。