
1) 【一句话结论】采用分层微服务架构,通过网关层令牌桶限流、多级缓存(本地+分布式+数据库)、异步任务队列(Kafka)及熔断降级,支撑百万级QPS的病毒查杀请求,确保高可用与低延迟。
2) 【原理/概念讲解】老师讲解关键概念:
3) 【对比与适用场景】
| 组件/策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 限流算法(令牌桶) | 持续生成令牌,请求消耗令牌 | 流量平滑,支持突发(burst) | 需控制平均速率(如百万级QPS需精确控制) | 参数(rate、burst)需基于实际流量测试 |
| 限流算法(漏桶) | 按固定速率放水 | 严格限制峰值,流量平滑 | 需严格限制峰值(如防止突发流量冲击) | 峰值控制严格,可能影响突发流量响应 |
| 本地缓存 | 服务进程内缓存(如LRU) | 响应快(微秒级),无网络开销 | 热数据(频繁访问的病毒特征库) | 容量有限,需合理设置 |
| 分布式缓存 | Redis集群 | 跨服务共享,高可用,支持高并发读写 | 大规模数据(百万级特征库),多实例部署 | 需考虑缓存预热与TTL |
| 数据库 | MySQL | 可靠持久化,支持复杂查询 | 冷数据(病毒库更新记录),更新频繁 | 需分库分表、索引优化 |
4) 【示例】
POST /scan?file_id=12345429 Too Many Requests;virus_scan),消费者异步调用360病毒库API,结果存入分布式缓存,返回异步任务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) 【追问清单】
7) 【常见坑/雷区】