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

设计一个支持百万级用户同时在线的登录系统,需要考虑哪些核心要素?如何保证高并发下的低延迟和可靠性?

Tencent软件开发-游戏客户端开发方向难度:困难

答案

1) 【一句话结论】

设计百万级用户登录系统,核心是通过分布式架构(负载均衡、缓存、数据库分片)、安全机制(密码加盐哈希、token防重放)、容错保障(限流、熔断、异步解耦),确保高并发下低延迟、数据可靠且安全。

2) 【原理/概念讲解】

从请求分发、数据存储、流程解耦、安全控制、容错保障五个维度讲解关键要素:

  • 负载均衡:通过Nginx(轮询/IP哈希/权重)将用户请求分发到应用集群,避免单点过载。需考虑会话粘性(如Cookie/Session复制,确保用户登录状态一致)。
  • 缓存层(Redis):存储高频登录状态(如用户token、用户信息),减少数据库压力。类比“超市货架”,热销商品(高频登录信息)放在货架,顾客直接拿,不用去仓库(数据库)。
    • 缓存击穿处理:热点key失效时,设置默认值(如“用户不存在”)、预加载热点数据(定时任务)、或用Redis锁(SETNX加过期时间)保证单次查询。
  • 数据库分片/读写分离:
    • 读写分离(主库写、从库读)提升读性能;
    • 分片按用户ID哈希到不同库,分散数据量。分片键选择需考虑业务扩展性(如用户ID范围变化时,迁移数据需停机或分阶段,避免影响业务)。
  • 异步消息队列(Kafka):解耦非实时业务(如登录通知、日志),削峰。需保证消息幂等性(如消息体带唯一标识,重复消费过滤)。
  • 安全机制:
    • 密码存储:用加盐哈希(如BCrypt),避免明文存储,防止暴力破解;
    • token生成:添加签名(如HMAC)和过期时间(如1小时),防重放攻击(token中包含时间戳或nonce,验证时检查是否过期或重复)。
  • 限流与熔断:
    • 限流(令牌桶算法):控制请求速率,避免流量过大导致系统崩溃;
    • 熔断(Hystrix):服务故障时拒绝请求,保护系统,阈值(如错误率超过50%时触发)。

3) 【对比与适用场景】

策略定义特性使用场景注意点
负载均衡分发请求到多个服务器轮询/IP哈希/权重高并发请求需考虑会话粘性(如Cookie)
缓存(Redis)存储高频数据高速、持久化登录状态、用户信息需设置过期时间,避免不一致
数据库分片按键哈希/范围切分数据分散数据量,提升读性能用户量巨大(百万级)分片键变更时需考虑数据迁移
消息队列异步处理业务解耦、削峰登录通知、日志需保证消息幂等性
限流(令牌桶)控制请求速率令牌生成速率决定QPS防止流量过大参数需动态调整(如负载变化)
熔断故障时拒绝请求快速失败服务故障时保护系统阈值需合理设置(如错误率)

4) 【示例】(登录流程伪代码)

用户请求:GET /login?user=xxx&pwd=xxx

  • 负载均衡(Nginx轮询)分发到应用服务器。
  • 应用服务器检查Redis缓存(key: user:xxx:login:token),有则直接返回token。
  • 无则查询分片数据库(主库),验证密码(BCrypt哈希比对)。
  • 验证成功,生成带签名的token(含用户ID、过期时间),存入Redis(key: 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无防重放机制,导致重复登录或恶意攻击。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1