让你设计一个 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、Metrics | QPS、延迟、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} |
| Host | api.example.com |
| Header | X-App-Version: 2.0 |
| Query | ?env=staging |
| Method | POST only |
与服务发现结合
控制面:Admin / 配置中心(etcd、Nacos、Consul、K8s CRD)
↓ 推送 / Watch
数据面:每个 Gateway 节点本地路由表 + 上游实例列表
↓
请求到达 → 匹配 route → 从 service registry 取 healthy 实例 → LB 选一个
| 组件 | 作用 |
|---|---|
| Service Discovery | K8s Service、Nacos、Consul 提供实例 IP:Port |
| 健康检查 | 剔除 unhealthy 节点 |
| 配置 Watch | etcd gRPC watch / Nacos 长轮询,秒级生效 |
| 本地缓存 | 数据面不强依赖控制面 RT;断连用最后已知配置 |
灰度 / 动态权重
| 策略 | 实现 |
|---|---|
| 权重随机 | 0~99 随机数 < weight 走 canary |
| 用户 sticky | hash(user_id) % 100 稳定分组 |
| Header 染色 | 测试账号带 x-canary: 1 |
| 地域 / 机房 | 路由到最近单元 |
注意: 灰度要 可观测(按 subset 打 metric),出问题一键切回 100% 稳定版本。完整灰度发布体系见 灰度发布系统设计。
常见实现选型(点到为止)
| 方案 | 特点 |
|---|---|
| Nginx + Lua / OpenResty | 高性能,配置或自研控制面 |
| Kong / APISIX | 插件生态,etcd 动态配置 |
| Envoy + xDS | K8s Ingress、Istio 数据面 |
| Spring Cloud Gateway | Java 栈,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 | 分布式限流计数 |
| 秒杀系统设计 | 网关限流在秒杀入口的应用 |
面试速记
- 核心功能: 路由、鉴权、限流、LB、协议转换、日志追踪、灰度。
- 动态路由: 配置中心 + 数据面 watch + 匹配规则 + 服务发现 + 权重灰度。
- 限流: 令牌桶/滑动窗口;单机内存 vs Redis 分布式;429 + Retry-After。
- 位置: 鉴权后、路由前限流;全局限流可更靠前。
- HA: 网关无状态水平扩展;配置最终一致;限流 Redis 故障策略要想好。