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

设计一个高并发的Web服务,用于处理360安全卫士的病毒查杀请求,要求支持百万级QPS,请描述系统架构,包括限流、缓存、异步处理等关键组件的设计思路。

360Web服务端开发工程师难度:困难

答案

1) 【一句话结论】采用分层微服务架构,通过网关层令牌桶限流、多级缓存(本地+分布式+数据库)、异步任务队列(Kafka)及熔断降级,支撑百万级QPS的病毒查杀请求,确保高可用与低延迟。

2) 【原理/概念讲解】老师讲解关键概念:

  • 限流(令牌桶算法):像“装水的桶”,持续生成令牌(每秒速率R,最大突发B),请求来时消耗令牌,令牌不足则拒绝。用于平滑流量,控制平均速率。漏桶类似“漏斗”,按固定速率放水,严格限制峰值。
  • 多级缓存:本地缓存(进程内,如Redis-lettuce)响应微秒级,存储热数据(如常见病毒特征库);分布式缓存(Redis集群)跨服务共享,处理冷数据(如新病毒特征);数据库(MySQL)作为最终一致性存储,存储病毒库元数据。
  • 异步处理:消息队列(如Kafka)解耦请求与病毒查杀,将请求放入队列,消费者异步调用360病毒库API,结果存入分布式缓存,避免阻塞主流程。
  • 负载均衡:Nginx+LVS分发请求到多个服务实例,提升并发能力。

3) 【对比与适用场景】

组件/策略定义特性使用场景注意点
限流算法(令牌桶)持续生成令牌,请求消耗令牌流量平滑,支持突发(burst)需控制平均速率(如百万级QPS需精确控制)参数(rate、burst)需基于实际流量测试
限流算法(漏桶)按固定速率放水严格限制峰值,流量平滑需严格限制峰值(如防止突发流量冲击)峰值控制严格,可能影响突发流量响应
本地缓存服务进程内缓存(如LRU)响应快(微秒级),无网络开销热数据(频繁访问的病毒特征库)容量有限,需合理设置
分布式缓存Redis集群跨服务共享,高可用,支持高并发读写大规模数据(百万级特征库),多实例部署需考虑缓存预热与TTL
数据库MySQL可靠持久化,支持复杂查询冷数据(病毒库更新记录),更新频繁需分库分表、索引优化

4) 【示例】

  • 请求示例:POST /scan?file_id=12345
  • 处理流程:
    1. 负载均衡(Nginx)分发请求到核心服务实例;
    2. 令牌桶限流:若令牌不足则返回429 Too Many Requests;
    3. 本地缓存查询:命中则返回结果;
    4. 无则分布式缓存查询:命中则返回结果;
    5. 无则异步处理:将请求放入Kafka队列(主题:virus_scan),消费者异步调用360病毒库API,结果存入分布式缓存,返回异步任务ID;
    6. 客户端通过任务ID查询结果(GET /scan/result?id=xxx)。
  • 伪代码(限流部分):
    class TokenBucket:
        def __init__(self, rate=1000, burst=1000):
            self.rate = rate  # 每秒生成令牌数
            self.burst = burst  # 最大突发令牌数
            self.tokens = burst
            self.last_time = time.time()
    
        def consume(self, n=1):
            now = time.time()
            elapsed = now - self.last_time
            self.tokens = min(self.burst, self.tokens + elapsed * self.rate)
            self.last_time = now
            return self.tokens >= n  # 令牌足够则返回True
    
    # 使用示例
    bucket = TokenBucket(rate=1000, burst=1000)
    if not bucket.consume():
        return "429 Too Many Requests"
    

5) 【面试口播版答案】
各位面试官好,针对360安全卫士病毒查杀的高并发Web服务设计,我的核心思路是构建分层微服务架构,通过限流、多级缓存、异步处理等组件支撑百万级QPS。首先,架构分层:前端用Nginx+LVS做负载均衡,分发请求到核心服务集群;核心服务拆分为网关(限流、路由)、业务处理(缓存、异步)、存储(数据库、缓存);最后用分布式存储保证数据一致性。然后限流:采用令牌桶算法,每秒生成1000个令牌,支持1000次突发,控制QPS在1万以内(根据实际流量测试调整),防止流量冲击。缓存分三级:本地缓存(如Redis-lettuce)存储热数据(常见病毒特征库),响应微秒级;分布式缓存(Redis集群)跨服务共享,处理冷数据(新病毒特征);数据库(MySQL)作为最终一致性存储,存储病毒库元数据。异步处理:用Kafka消息队列解耦请求和病毒查杀,将请求放入队列,由消费者异步调用360病毒库API,结果存入分布式缓存,避免阻塞主流程。这样设计后,系统能够支撑百万级QPS,同时保证高可用和低延迟。

6) 【追问清单】

  • 如何保证缓存一致性?
    回答要点:本地缓存与分布式缓存通过缓存预热(初始化时加载热数据到本地+分布式),分布式缓存与数据库通过读写分离+TTL+异步更新(如数据库更新后,通过消息队列通知缓存更新),避免缓存雪崩。
  • 异步任务队列如何保证可靠性?
    回答要点:消息队列持久化(Kafka的持久化主题,确保消息不丢失),消费者幂等性(通过唯一任务ID处理重复消息,避免重复查杀),重试机制(失败后重试3次,超时后标记为失败)。
  • 服务拆分后如何处理跨服务调用?
    回答要点:服务间通过RESTful API+异步消息队列解耦,网关统一路由,避免直接调用,提高可扩展性;接口设计遵循统一规范(如版本、参数、返回格式),便于维护。
  • 熔断机制如何设计?
    回答要点:针对核心服务(如病毒查杀API)设置熔断器,当调用失败率超过阈值(如50%)或响应时间超过阈值(如500ms)时触发熔断,返回降级结果(如“查杀中,稍后再试”),防止服务雪崩。
  • 数据库如何优化?
    回答要点:分库分表(按文件ID哈希分表,如file_id % 1000),索引优化(对file_id建立索引,加速查询),读写分离(主从复制,主库写,从库读),批量操作(如批量插入病毒特征,减少数据库压力)。

7) 【常见坑/雷区】

  • 限流位置错误:将限流放在应用层而非网关,导致每个实例都要处理限流逻辑,增加压力。
  • 缓存一致性处理不足:未设置缓存预热或TTL,导致大量请求穿透缓存,冲击数据库。
  • 异步任务丢失:未考虑消息队列持久化或消费者幂等性,导致病毒查杀任务丢失。
  • 服务拆分后接口设计混乱:未统一接口规范,导致跨服务调用混乱,影响扩展性。
  • 熔断参数设置不当:熔断阈值过低导致频繁熔断,影响可用性;过高则无法及时熔断,导致服务雪崩。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1