微服务网关治理:路由、认证授权、限流、灰度、错误语义与排查
API Gateway 是微服务系统的统一入口。它不是“高级 Nginx”,也不是把所有业务都搬到入口层,而是把路由、认证、粗粒度授权、限流、跨域、灰度、Header 清洗、Trace、审计和入口错误语义统一起来。
Spring Cloud Gateway 的具体实现见:Spring Cloud Gateway、Gateway内部链路与生产治理、Gateway统一认证与OAuth2。本页从分布式系统角度解释网关在整体架构里的职责边界和生产排查。
学习目标
学完本页要能回答:
- 网关在微服务里解决什么,不解决什么。
- 一次请求从 Gateway 到下游服务的完整链路。
- Gateway、Nginx、Ingress、Service Mesh、业务服务各自负责什么。
- Gateway 怎样做统一认证,OAuth2/OIDC/JWT 在微服务里怎样落地。
- 为什么 Gateway 鉴权后,下游服务仍要授权。
- 网关限流、服务限流、Sentinel、WAF 的边界是什么。
- Gateway 404、401、403、429、502、503、504 怎么定位。
一、Gateway 的职责边界
flowchart TD
A["客户端"] --> B["WAF/CDN/Nginx"]
B --> C["API Gateway"]
C --> D["认证、限流、灰度、路由"]
D --> E["业务服务"]
E --> F["业务权限、事务、状态机"]Gateway 适合做:
| 能力 | 说明 |
|---|---|
| 统一入口 | 客户端只面对一个入口域名 |
| 路由转发 | 根据 Path、Host、Header、Method 转发 |
| 认证 | 校验登录态、JWT、Access Token |
| 粗授权 | 路由级、角色级、Scope级拦截 |
| 限流 | IP、用户、租户、接口级入口限流 |
| 灰度 | 根据用户、租户、版本、Header 分流 |
| Header 清洗 | 移除外部伪造身份头,写入可信上下文 |
| Trace 和审计 | 生成 traceId、记录入口日志 |
| 跨域和协议适配 | CORS、路径重写、部分协议桥接 |
Gateway 不适合做:
| 不适合 | 原因 |
|---|---|
| 复杂业务规则 | 会让入口层变厚,业务规则分散 |
| 数据库事务 | 网关不应参与领域事务和状态机 |
| 复杂聚合查询 | 容易拖慢入口,形成全站瓶颈 |
| 长耗时阻塞 IO | 事件循环或入口线程被占住 |
| 替代业务授权 | 资源归属、租户、医院、科室权限必须在服务层校验 |
一句话:Gateway 管入口秩序,业务服务管业务事实。
二、一次请求在网关中的完整链路
flowchart TD
A["请求进入Gateway"] --> B["生成或读取traceId"]
B --> C["匹配Route"]
C --> D["校验Predicate"]
D --> E["前置Filter"]
E --> F["认证和Header清洗"]
F --> G["限流和灰度标签"]
G --> H["lb://服务名触发负载均衡"]
H --> I["选择ServiceInstance"]
I --> J["HTTP客户端转发"]
J --> K["下游服务处理"]
K --> L["后置Filter记录指标"]
L --> M["返回客户端"]关键点:
- Route 决定去哪儿。
- Predicate 决定这个请求是否匹配这条路由。
- Filter 决定转发前后做什么。
lb://service-name不是注册中心转发,而是 Gateway 侧 LoadBalancer 从本地实例快照选一个真实IP:Port。- Netty、HTTP Client、连接池才是真正发请求的一层。
三、Gateway、Nginx、Ingress、Mesh 怎么分工
| 组件 | 更适合做什么 | 不适合替代什么 |
|---|---|---|
| Nginx | 静态资源、TLS终止、反向代理、基础负载 | 微服务细粒度治理和业务身份 |
| Kubernetes Ingress | K8s 集群入口路由 | 复杂业务鉴权和服务内授权 |
| API Gateway | 微服务入口治理、认证、限流、灰度、路由 | 领域业务和数据库事务 |
| Service Mesh | 服务间 mTLS、路由、重试、熔断、指标 | 用户权限、业务幂等和状态机 |
| 业务服务 | 业务规则、资源授权、事务、状态机 | 全局入口流量防护 |
不要在多层重复配置同一个能力而没有 Owner。例如 Nginx、Gateway、Mesh、Feign、业务代码都做重试,会形成重试风暴;Gateway 和服务都限流可以,但保护对象和指标要不同。
四、统一认证和 OAuth2/OIDC
OAuth2 主要解决授权委托,OIDC 在 OAuth2 之上补充登录身份。微服务常见模式是:认证授权中心签发 Token,Gateway 做入口校验和上下文清洗,业务服务作为 Resource Server 再次校验 Token 并做业务授权。
flowchart TD
A["用户登录"] --> B["认证授权中心"]
B --> C["签发Access Token和ID Token"]
C --> D["客户端携带Bearer Token访问Gateway"]
D --> E["Gateway校验签名、过期、issuer、audience"]
E --> F["Gateway清洗外部身份Header"]
F --> G["写入受控用户上下文或透传Token"]
G --> H["业务服务再次校验Token"]
H --> I["Service层校验数据权限"]Gateway 可做的认证:
| 能力 | 说明 |
|---|---|
| JWT签名校验 | 用 JWK 公钥校验 Token 未被篡改 |
| 过期时间 | 校验 exp、nbf |
| 发行方 | 校验 iss |
| 受众 | 校验 aud,防止 Token 被其他系统误用 |
| Scope/角色粗拦截 | 比如 /admin/** 需要 admin scope |
| Header 清洗 | 删除外部传入的 X-User-Id,由网关重写可信值 |
下游仍要做的授权:
| 授权 | 示例 |
|---|---|
| 方法权限 | 是否能调用“删除资产” |
| 数据权限 | 是否能查看这个医院、科室、租户的数据 |
| 状态权限 | 订单已完成不能再取消 |
| 审计 | 谁在什么时候访问了哪份敏感数据 |
如果只在 Gateway 校验用户是否登录,下游完全信任 X-User-Id,一旦有人绕过 Gateway 或伪造 Header,就可能越权。
五、服务间调用授权
微服务内部调用分两类:
| 类型 | 做法 | 示例 |
|---|---|---|
| 代表用户的调用 | 透传用户 Access Token 或受控身份上下文 | 用户查资产,资产服务调用权限服务 |
| 系统任务调用 | 使用 client_credentials 获取服务账号 Token | 定时采集任务调用资产入库服务 |
不要用“伪造管理员用户”解决服务间调用,这会让审计、最小权限和责任边界全部失效。系统账号也要有 scope、租户范围、接口范围和过期时间。
六、Gateway 限流怎么设计
限流 key 要按保护对象设计。
| Key | 适合场景 | 风险 |
|---|---|---|
| IP | 匿名接口、防爬 | NAT、代理会误伤 |
| 用户ID | 登录用户接口 | 登录前不可用 |
| 租户ID | SaaS、多医院系统 | 热租户可能被限制 |
| 接口ID | 保护某个高成本接口 | 无法区分调用主体 |
| 租户+接口 | 商业系统常用 | key 基数较高 |
| 用户+资源 | 细粒度防刷 | 规则和指标复杂 |
网关限流和服务内限流都需要,但目标不同:
- 网关尽早拒绝明显超预算流量,保护整个后端。
- 服务内限流理解业务参数,保护线程池、数据库、Redis、第三方。
- Sentinel、Resilience4j、Redis Lua、Envoy 都能做限流,但要明确 Owner。
- 限流失败返回 429,认证失败返回 401,权限不足返回 403,不要混用。
七、灰度和路由
Gateway 灰度常见依据:
| 条件 | 示例 |
|---|---|
| 用户 | 内部员工、白名单用户 |
| 租户 | 指定医院或企业租户 |
| Header | X-Gray-Version: v2 |
| Cookie | 前端灰度标记 |
| 权重 | 1%、5%、20% |
| 地域 | 上海机房、北京机房 |
flowchart TD
A["请求进入Gateway"] --> B["认证得到用户和租户"]
B --> C["计算灰度标签"]
C --> D["写入可信Header"]
D --> E["LoadBalancer按metadata过滤实例"]
E --> F["转发到v1或v2服务"]灰度规则必须可观测:每个请求要能查到 routeId、灰度标签、目标服务版本、目标 IP、是否回退、最终状态码。
八、错误语义
| 状态码 | 含义 | 排查方向 |
|---|---|---|
| 401 | 未认证或 Token 无效 | Token、签名、公钥、过期、issuer |
| 403 | 已认证但权限不足 | scope、角色、租户、资源归属 |
| 404 | 没命中路由或下游资源不存在 | Route、Path、Rewrite、下游接口 |
| 429 | 被限流 | 限流 key、阈值、突发、租户流量 |
| 502 | 网关收到下游异常响应或连接异常 | 下游连接、协议、异常 |
| 503 | 没有可用实例或熔断 | 注册中心、LB候选、熔断状态 |
| 504 | 下游超时 | Gateway超时、下游P99、连接池、线程池 |
注意:504 不代表下游没有执行。写请求从 Gateway 超时后,客户端不能直接换请求号再提交一次,必须靠业务幂等号查询事实。
九、生产 Runbook
9.1 Gateway 404
- 查是否命中正确 Route。
- 查 Path、Method、Host、Header Predicate。
- 查 StripPrefix、RewritePath 是否改错。
- 查下游 Controller 路径和网关转发路径是否一致。
- 查动态路由是否刷新到当前实例。
9.2 Gateway 503
- 查
lb://service-name服务名是否正确。 - 查注册中心是否有健康实例。
- 查 namespace、group、cluster 是否一致。
- 查 LoadBalancer 过滤后候选是否为空。
- 查灰度 metadata 是否把实例全部过滤掉。
- 查熔断器是否打开。
9.3 Gateway 504
- 查 Gateway route timeout。
- 查下游服务 P95/P99。
- 查 Gateway 到下游连接池等待。
- 查下游线程池、慢 SQL、锁等待、GC。
- 查是否有重试放大。
- 写请求按幂等号查询事实。
9.4 鉴权偶发失败
- 查 JWK 公钥是否刷新。
- 查多个 Gateway 实例时间是否漂移。
- 查 Token 的
iss、aud、exp。 - 查 Header 是否被 Nginx、Gateway 或下游清洗。
- 查是否有新旧密钥轮换窗口。
十、JDK 8 Demo:可信用户上下文
下面 Demo 演示 Gateway 为什么要清洗外部身份 Header,再写入受控上下文。
import java.util.HashMap;
import java.util.Map;
public class GatewayHeaderSanitizeDemo {
static Map<String, String> filter(Map<String, String> headers, String tokenUserId) {
Map<String, String> sanitized = new HashMap<String, String>(headers);
sanitized.remove("X-User-Id");
sanitized.remove("X-Tenant-Id");
sanitized.put("X-User-Id", tokenUserId);
sanitized.put("X-Auth-Source", "gateway");
return sanitized;
}
public static void main(String[] args) {
Map<String, String> headers = new HashMap<String, String>();
headers.put("X-User-Id", "admin");
headers.put("X-Tenant-Id", "other-tenant");
Map<String, String> result = filter(headers, "user-1001");
System.out.println(result);
}
}这个 Demo 说明:外部请求头不能直接信。真实系统还要校验 JWT、issuer、audience、scope、签名和过期时间,下游也要再次校验 Token 或受信任内部身份。
十一、面试标准回答
Gateway 是微服务统一入口,负责路由、认证、粗粒度授权、限流、灰度、Header 清洗、Trace 和审计。一次请求进入 Gateway 后,先匹配 Route 和 Predicate,再执行前置 Filter 做认证、限流和灰度,lb://服务名 会触发客户端负载均衡选择真实实例,最后由 HTTP Client 转发到下游,响应回来后执行后置 Filter。Gateway 不能替代业务服务授权,尤其数据权限、租户权限、状态机和事务必须在服务层校验。OAuth2/OIDC 场景下,认证中心签发 Token,Gateway 校验 Token 并清洗外部 Header,下游服务作为 Resource Server 再次校验并做资源授权。排查时按 401、403、404、429、503、504 分层定位。
十二、本章小结
Gateway 的核心价值是把入口横切能力统一起来,但它必须保持“薄”。它是流量入口和安全第一道门,不是业务大脑。生产级网关要讲清职责边界、认证授权链路、限流对象、灰度标签、负载均衡、错误语义和排查证据。
