跳到主要内容

让你设计一个 API 网关,需要考虑哪些核心功能?如何实现动态路由和限流?

API 网关是 南北向流量统一入口:对外暴露 API,对内路由到微服务。面试先列 核心能力,再深答 动态路由 与 限流 的实现。HTTP 语义见 API 设计与 HTTP 实践;限流算法与熔断见 限流熔断与降级;分布式计数见 Redis;鉴权见 认证与授权。

网关解决什么问题​

痛点网关怎么帮
客户端对接 N 个服务统一域名 / 路径
鉴权、限流散落各服务横切能力集中
灰度、版本、协议差异路由与转换
可观测性碎片化统一 access log、trace id
Client / Mobile / Web
↓
API Gateway(SSL、鉴权、限流、路由、日志)
↓
┌────┬────┬────┐
SvcA SvcB SvcC …

核心功能清单(面试按层答)​

类别功能说明
路由路径/Host/Header 匹配/api/orders → order-service
负载均衡round-robin、least-conn、一致性 hash
灰度 / 金丝雀按比例、标签、用户尾号分流
安全TLS 终结边缘解密,内网可 HTTP/mTLS
认证鉴权JWT/API Key/OAuth;401/403 —— 认证与授权
WAF / IP 黑白名单防 SQLi、CC
流量治理限流全站/用户/接口 —— 下文详述
熔断降级下游不健康快速失败 —— 限流熔断与降级
超时 / 重试网关级默认 + 路由级覆盖
协议HTTP ↔ gRPC 转换对外 REST,对内 gRPC
WebSocket 代理长连接升级
可观测Access Log、MetricsQPS、延迟、4xx/5xx、限流命中
分布式追踪注入/透传 trace_id、request_id
生态插件 / 过滤器链鉴权 → 限流 → 路由 → 日志,顺序可配
配置中心路由、限流规则 热更新

MVP 可只做:路由 + 鉴权 + 限流 + 日志;其余按追问展开。

动态路由怎么实现​

目标: 不改代码、不重启,更新「哪条请求 → 哪个上游集群」。

路由规则模型​

# 逻辑配置示例
routes:
- id: order-v2-canary
match:
path: /api/v2/orders/**
headers:
x-canary: "1" # 可选
upstream:
service: order-service
subset: v2 # 版本标签
weight: 10 # 灰度 10%
- id: order-v2-default
match:
path: /api/v2/orders/**
upstream:
service: order-service
subset: v1
weight: 90
匹配维度例子
Path/api/users/{id}
Hostapi.example.com
HeaderX-App-Version: 2.0
Query?env=staging
MethodPOST only

与服务发现结合​

控制面:Admin / 配置中心(etcd、Nacos、Consul、K8s CRD)
↓ 推送 / Watch
数据面:每个 Gateway 节点本地路由表 + 上游实例列表
↓
请求到达 → 匹配 route → 从 service registry 取 healthy 实例 → LB 选一个
组件作用
Service DiscoveryK8s Service、Nacos、Consul 提供实例 IP:Port
健康检查剔除 unhealthy 节点
配置 Watchetcd gRPC watch / Nacos 长轮询,秒级生效
本地缓存数据面不强依赖控制面 RT;断连用最后已知配置

灰度 / 动态权重​

策略实现
权重随机0~99 随机数 < weight 走 canary
用户 stickyhash(user_id) % 100 稳定分组
Header 染色测试账号带 x-canary: 1
地域 / 机房路由到最近单元

注意: 灰度要 可观测(按 subset 打 metric),出问题一键切回 100% 稳定版本。完整灰度发布体系见 灰度发布系统设计。

常见实现选型(点到为止)​

方案特点
Nginx + Lua / OpenResty高性能,配置或自研控制面
Kong / APISIX插件生态,etcd 动态配置
Envoy + xDSK8s Ingress、Istio 数据面
Spring Cloud GatewayJava 栈,RouteDefinition 可刷

面试说清 「配置中心 → 数据面路由表 → 匹配 + 服务发现 + LB」 即可,不必绑定某一产品。

限流怎么实现​

目标: 超限 早拒绝(429),保护网关与下游。算法详见 限流熔断与降级。

限流维度​

维度场景
全局限流保护整个网关或集群
路由 / API热点接口单独配额
用户 / AppId租户公平
IP防刷
组合api + user 二维配额

算法选择​

算法网关常用说明
令牌桶很常用允许一定突发;Nginx limit_req 类似漏桶/桶组合
滑动窗口分布式比固定窗口平滑
固定窗口简单边界双倍突发问题

单机 vs 分布式​

单机限流(每 gateway 节点):

  • 内存计数,性能最好
  • 节点数变时要 按实例数分摊配额(每机 limit/N),否则总限流过宽

分布式限流(集群一致):

请求 → Gateway 节点
→ Redis INCR + EXPIRE(滑动窗口 / 令牌桶 lua)
→ 未超限:放行;超限:429 + Retry-After

Redis Lua 示例思路(滑动窗口计数):

-- KEY=ratelimit:{route}:{userId}:{windowStart}
local c = redis.call('INCR', KEYS[1])
if c == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end
return c <= tonumber(ARGV[2])
点说明
热 key大租户独立 key;本地令牌桶 + Redis 仅同步「全局配额」混合方案
失败策略Redis 不可用:fail-open(放行)还是 fail-close(拒绝)——金融常 close
响应429 + Retry-After —— API 设计与 HTTP 实践

在网关中的位置​

请求
→ SSL
→ 鉴权(401/403)
→ **限流(429)** ← 尽早,省下游
→ 路由
→ 熔断(可选)
→ 反向代理 upstream

插件链里 限流通常在鉴权之后(按用户限)或 之前(全站 DDoS 防护)——两层可并存。

高可用与性能​

点做法
网关无状态水平扩展 + LB 前置
配置最终一致各节点 watch,同一 revision
延迟路由匹配 Trie/前缀树;限流走本地 + 异步同步
不成为单点多 AZ 部署;控制面也要 HA

常见坑​

坑说明
限流在业务层才做流量已打穿,网关应早拒
分布式限流热 key单 Redis key 成瓶颈
灰度无回滚配置一键切 100% 稳定版
全 200 业务码429/401 应用真实 HTTP 状态码
重试风暴网关或客户端无限重试放大故障

面试参考答法(90 秒)​

API 网关是统一入口,核心功能我会分路由、安全、流量治理和可观测。

路由包括路径匹配、负载均衡、与服务发现联动,以及灰度权重。动态路由靠配置中心存 Route 定义,数据面 watch 热更新,请求来时匹配规则,再从注册中心拿 healthy 实例转发。

限流在鉴权后尽早做,算法用令牌桶或滑动窗口;单节点内存限流简单,集群一致用 Redis Lua 计数,超限返回 429 和 Retry-After。可按全局、API、用户多维度配额。同时配合熔断、超时、统一 trace id 和 access log。

实现上 Nginx/OpenResty、Kong、APISIX、Envoy 都是这一模型的不同产品化形态。

延伸阅读​

篇关系
API 设计与 HTTP 实践429、版本、request_id
限流熔断与降级算法、熔断
认证与授权网关鉴权
Redis分布式限流计数
秒杀系统设计网关限流在秒杀入口的应用

面试速记​

  1. 核心功能: 路由、鉴权、限流、LB、协议转换、日志追踪、灰度。
  2. 动态路由: 配置中心 + 数据面 watch + 匹配规则 + 服务发现 + 权重灰度。
  3. 限流: 令牌桶/滑动窗口;单机内存 vs Redis 分布式;429 + Retry-After。
  4. 位置: 鉴权后、路由前限流;全局限流可更靠前。
  5. HA: 网关无状态水平扩展;配置最终一致;限流 Redis 故障策略要想好。