154 lines
4.4 KiB
Markdown
154 lines
4.4 KiB
Markdown
---
|
||
tags: [microservice, api-gateway, kong, apisix, spring-cloud-gateway]
|
||
create time: 2026-05-05
|
||
---
|
||
|
||
# API 网关
|
||
|
||
## 概述
|
||
|
||
API Gateway 是所有外部请求的统一入口,承担以下职责:
|
||
|
||
```mermaid
|
||
graph LR
|
||
Client["客户端 App / Web"] --> GW["API Gateway"]
|
||
GW --> Auth["鉴权 & 限流"]
|
||
GW --> Route["路由转发"]
|
||
GW --> Transform["协议转换"]
|
||
GW --> Log["日志 & 监控"]
|
||
GW -.-> CB[(配置中心)]
|
||
```
|
||
|
||
常见实现:**Kong、APISIX、Spring Cloud Gateway、Nginx + Lua**。
|
||
|
||
## 网关应该做什么?
|
||
|
||
> [!summary] 网关职责清单
|
||
|
||
| ✅ 适合放 | ❌ 不应该放 |
|
||
|---------|-----------|
|
||
| 鉴权与认证 | 业务逻辑(如订单创建) |
|
||
| 限流熔断 | 复杂的数据聚合查询 |
|
||
| HTTPS 终结 | 大量 CPU 密集型计算 |
|
||
| 请求/响应转换 | 涉及数据库写操作 |
|
||
| 路由分发 | 跨服务事务管理 |
|
||
| 日志 & 监控 | 邮件/短信发送等异步任务 |
|
||
|
||
> [!tip] 核心原则
|
||
> **网关保持瘦**——它是 traffic cop(交通警察),不是 warehouse manager(仓库管理员)。重逻辑应下沉到业务服务。
|
||
|
||
### 分层鉴权模型
|
||
|
||
> [!question] 权衡题
|
||
> 有人说:"鉴权放到网关统一做,避免每个服务重复写。"但如果某个内部服务不需要鉴权呢?或者不同团队要求不同的鉴权方式呢?
|
||
|
||
**分层鉴权架构**:
|
||
|
||
```mermaid
|
||
graph TB
|
||
External["外部用户"] --> GW["API Gateway<br/>JWT 校验 + OAuth2"]
|
||
GW --> S1[公开接口<br/>无需额外鉴权]
|
||
GW --> S2[内部接口<br/>Service Token]
|
||
|
||
S1 --> UserSvc[[User Service]]
|
||
S2 --> OrderSvc[[Order Service]]
|
||
S2 --> PaySvc[[Payment Service]]
|
||
|
||
OrderSvc -->|"mTLS + JWT"| DB[(DB)]
|
||
PaySvc -->|"mTLS + JWT"| DB
|
||
```
|
||
|
||
- **第一层(网关)**:校验外部用户的 JWT/OAuth Token,拦截非法请求
|
||
- **第二层(服务间)**:通过 Service Token 或 mTLS 保证调用方身份可信
|
||
- **第三层(数据层)**:RBAC / ABAC 细粒度权限控制
|
||
|
||
## 路由策略
|
||
|
||
### 基础路由规则
|
||
|
||
```yaml
|
||
# APISIX 路由示例
|
||
routes:
|
||
- uri: /api/orders/*
|
||
upstream:
|
||
nodes:
|
||
"order-service:8080": 1
|
||
type: roundrobin
|
||
|
||
- uri: /api/payments/*
|
||
upstream:
|
||
nodes:
|
||
"payment-service:8080": 1
|
||
type: roundrobin
|
||
```
|
||
|
||
### 高级路由策略
|
||
|
||
| 策略 | 场景 | 示例 |
|
||
|------|------|------|
|
||
| **路径匹配** | 按 URL 前缀路由 | `/api/v1/*` → v1 版本服务 |
|
||
| **Header 匹配** | A/B 测试、灰度发布 | `x-canary: true` → 新版本 |
|
||
| **权重路由** | 金丝雀发布 | 90% 流量 → v1, 10% → v2 |
|
||
| **正则匹配** | 复杂 URL 模式 | `/api/user/(?P<id>\d+)/*` |
|
||
|
||
## 网关插件体系
|
||
|
||
网关的核心价值在于 **可插拔的中间件链**,类似 Express/Koa 的 middleware 概念。
|
||
|
||
```mermaid
|
||
graph LR
|
||
Req["Request"] -->|Plugin 1| RateLimiter["限流"]
|
||
RateLimiter -->|Plugin 2| Auth["鉴权"]
|
||
Auth -->|Plugin 3| CBR["熔断"]
|
||
CBR -->|Plugin 4| Transform["协议转换"]
|
||
Transform -->|Plugin 5| Logger["日志"]
|
||
Logger --> Backend["Backend Service"]
|
||
```
|
||
|
||
### 常用插件列表
|
||
|
||
| 插件 | 作用 | 推荐算法 |
|
||
|------|------|---------|
|
||
| **Rate Limiting** | 防刷限流 | 令牌桶 / 漏桶 |
|
||
| **CORS** | 跨域处理 | 预检缓存 |
|
||
| **IP 黑白名单** | 访问控制 | Redis Bloom Filter |
|
||
| **Response Rewrite** | 修改响应体 | JSON Patch |
|
||
| **Request Transformation** | Header/Body 改写 | Map-based |
|
||
| **Prometheus Exporter** | 指标采集 | 自动埋点 |
|
||
| **Fault Injection** | 混沌测试注入延迟/错误 | 按比例注入 |
|
||
|
||
## 网关的高可用设计
|
||
|
||
```mermaid
|
||
graph TB
|
||
DNS["DNS / CLB"] --> GW1["Gateway Node 1"]
|
||
DNS --> GW2["Gateway Node 2"]
|
||
|
||
subgraph GW_Cluster["网关集群"]
|
||
GW1
|
||
GW2
|
||
end
|
||
|
||
GW1 --> B1["backend-pool-v1"]
|
||
GW2 --> B2["backend-pool-v1"]
|
||
|
||
B1 --> Svc1[[order-service]]
|
||
B1 --> Svc2[[user-service]]
|
||
B2 --> Svc1
|
||
B2 --> Svc2
|
||
|
||
GW1 -.-> Config["配置中心 (同步)"]
|
||
GW2 -.-> Config
|
||
```
|
||
|
||
**关键点**:
|
||
- 网关无状态设计,可横向扩展
|
||
- 配置通过注册中心实时同步,无需重启
|
||
- 多节点前接负载均衡器(CLB/Nginx)
|
||
|
||
## 关联笔记
|
||
|
||
- [[02-服务治理/服务发现/README]] — 网关需要订阅服务实例列表
|
||
- [[02-服务治理/流量治理/README]] — 高级路由和灰度发布的延伸
|
||
- [[hzh/MS/API 设计原则]] — API Gateway 的设计与 REST/gRPC 选型
|