1299 字
3 分钟
API 网关:微服务的统一入口
某社交平台在明星官宣瞬间涌入百万用户,API 请求量暴增 50 倍。如果没有限流保护,后端服务会在几秒内被压垮,所有用户都无法访问。API 网关作为系统统一入口,承担限流、熔断、路由等横切关注点,是微服务架构中不可或缺的组件。
一、API 网关的核心职责
API 网关是所有外部请求进入微服务系统的唯一入口,将后端多个服务聚合为统一的 API 接口。
| 职责 | 说明 |
|---|---|
| 路由转发 | 根据路径、Host、Header 将请求分发到对应后端服务 |
| 认证鉴权 | 统一处理 JWT、OAuth2、API Key 等认证逻辑 |
| 限流熔断 | 保护后端服务免受流量冲击 |
| 协议转换 | HTTP/gRPC/WebSocket 等协议互转 |
| 灰度发布 | 按权重或特征分流到不同版本 |
| 日志监控 | 收集请求日志和性能指标 |
二、限流算法
2.1 令牌桶(Token Bucket)
令牌桶以固定速率生成令牌,请求消耗令牌。桶满时令牌不再增加,桶空时请求被拒绝。
特点:允许突发流量(桶中有积累的令牌),但长期平均速率不超过令牌生成速率。
class TokenBucket: def __init__(self, rate, capacity): self.rate = rate # 每秒生成令牌数 self.capacity = capacity # 桶容量 self.tokens = capacity self.last_refill = time.time()
def allow(self, tokens=1): self._refill() if self.tokens >= tokens: self.tokens -= tokens return True return False
def _refill(self): now = time.time() elapsed = now - self.last_refill self.tokens = min(self.capacity, self.tokens + elapsed * self.rate) self.last_refill = now适用场景:API 限流,允许合理突发。
2.2 滑动窗口(Sliding Window)
精确统计任意时间窗口内的请求数,避免固定窗口的临界突发问题。
class SlidingWindow: def __init__(self, window_size, max_requests): self.window_size = window_size self.max_requests = max_requests self.requests = deque()
def allow(self): now = time.time() while self.requests and now - self.requests[0] > self.window_size: self.requests.popleft() if len(self.requests) < self.max_requests: self.requests.append(now) return True return False适用场景:精确限流,如每分钟 100 次。
2.3 漏桶(Leaky Bucket)
请求以固定速率流出,桶满时新请求被拒绝。输出速率恒定,无法应对突发。
适用场景:流量整形,保证下游服务收到均匀的请求。
2.4 算法对比
| 算法 | 突发处理 | 精度 | 实现复杂度 | 适用场景 |
|---|---|---|---|---|
| 令牌桶 | 允许合理突发 | 中 | 中 | API 限流 |
| 滑动窗口 | 不允许 | 高 | 高 | 精确限流 |
| 漏桶 | 不允许 | 中 | 低 | 流量整形 |
| 固定窗口 | 临界 2 倍突发 | 低 | 低 | 简单限流 |
三、熔断器模式
3.1 为什么需要熔断
当后端服务出现故障时,如果不及时切断调用链,会导致:
- 调用方线程池耗尽
- 故障蔓延到上游服务
- 系统整体崩溃(雪崩效应)
熔断器在故障达到阈值时自动切断调用,快速失败而非等待超时。
3.2 状态机
flowchart TB
A[Closed] -->|失败率超过阈值| B[Open]
B -->|超时后探测| C[Half-Open]
C -->|探测成功| A
C -->|探测失败| B
| 状态 | 行为 |
|---|---|
| Closed(关闭) | 正常放行请求,统计失败率 |
| Open(打开) | 直接拒绝请求,快速失败 |
| Half-Open(半开) | 放行少量探测请求,判断是否恢复 |
3.3 熔断器实现
class CircuitBreaker: def __init__(self, failure_threshold=5, timeout=60, success_threshold=3): self.failure_threshold = failure_threshold self.timeout = timeout self.success_threshold = success_threshold self.state = "CLOSED" self.failures = 0 self.successes = 0 self.last_failure_time = None
def call(self, func, *args, **kwargs): if self.state == "OPEN": if time.time() - self.last_failure_time >= self.timeout: self.state = "HALF_OPEN" self.successes = 0 else: raise CircuitOpenError("熔断器打开,请求被拒绝")
try: result = func(*args, **kwargs) self._on_success() return result except Exception as e: self._on_failure() raise
def _on_success(self): if self.state == "HALF_OPEN": self.successes += 1 if self.successes >= self.success_threshold: self.state = "CLOSED" self.failures = 0
def _on_failure(self): self.failures += 1 self.last_failure_time = time.time() if self.failures >= self.failure_threshold: self.state = "OPEN"3.4 熔断配置参考
resilience4j: circuitbreaker: instances: backendA: slidingWindowSize: 10 failureRateThreshold: 50 waitDurationInOpenState: 60s permittedNumberOfCallsInHalfOpenState: 3四、灰度发布
4.1 权重分流
按比例将流量分配到不同版本:
canary: weight: 10 # 10% 流量到新版本 targets: - upstream: user-service-v1 weight: 90 - upstream: user-service-v2 weight: 104.2 特征分流
根据请求特征(Header、Cookie、IP)分流:
canary: match: - header: X-Beta-Tester: "true"4.3 金丝雀发布流程
1. 部署新版本到 1 个实例2. 配置 5% 流量到新版本3. 监控错误率和延迟4. 逐步增加流量比例:5% → 10% → 25% → 50% → 100%5. 全量切换后关闭旧版本五、网关与服务发现的协作
API 网关依赖服务发现获取后端实例列表:
sequenceDiagram
participant G as API 网关
participant R as 注册中心
participant S as 服务实例
G->>R: 订阅服务变更
R-->>G: 推送实例列表
G->>S: 转发请求(负载均衡)
网关需要处理以下场景:
- 实例上线:更新路由表,新实例开始接收流量
- 实例下线:移除路由表,请求不再转发到已下线实例
- 实例异常:熔断器触发,暂时切断对该实例的请求
六、主流网关对比
| 网关 | 语言 | 特点 | 性能 | 适用场景 |
|---|---|---|---|---|
| Kong | Lua | 插件丰富、生态完善 | 高 | 企业级 API 管理 |
| Spring Cloud Gateway | Java | Spring 生态集成 | 中 | Spring Cloud 微服务 |
| Envoy | C++ | 服务网格原生 | 极高 | Istio 数据平面 |
| APISIX | Lua | 云原生、动态配置 | 高 | Kubernetes 环境 |
| Nginx | C | 高性能、稳定 | 极高 | 反向代理、静态资源 |
七、网关性能优化
| 优化项 | 方法 | 预期收益 |
|---|---|---|
| 连接池 | 复用后端连接 | 延迟降低 30-50% |
| 异步 IO | 非阻塞处理 | 吞吐量提升 2-3 倍 |
| 响应缓存 | 缓存静态/半静态响应 | QPS 提升 5-10 倍 |
| HTTP/2 | 多路复用、头部压缩 | 延迟降低 20-30% |
# Kong 性能配置nginx_proxy: worker_processes: auto worker_connections: 16384 keepalive_timeout: 60s keepalive_requests: 1000八、实践建议
- 网关作为统一入口:所有外部请求必须经过网关,后端服务不直接暴露
- 限流算法选择:令牌桶适合 API 限流,漏桶适合流量整形
- 熔断器配置:根据业务 SLA 设置失败率阈值和超时时间
- 灰度发布:先小范围验证,再逐步放量
- 监控告警:网关是流量入口,必须配备完善的监控
API 网关解决了微服务架构中”南北向”流量(从外部进入集群)的管理问题。理解限流、熔断、灰度发布等核心机制,才能构建可靠的微服务入口。网关与服务发现、分布式追踪等组件紧密协作,共同构成微服务的基础设施层。
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时
相关文章 智能推荐
1
Istio:服务网格的工程实践
分布式系统深入 深入解析 Istio 服务网格——Sidecar 代理、流量管理、安全策略与可观测性的工程实践
2
服务发现:微服务通信的基础设施
分布式系统深入 深入理解服务发现机制——从 DNS 到注册中心,客户端发现与服务端发现的差异与工程实践
3
Saga 模式:长事务的编排方案
分布式系统深入 深入解析 Saga 模式——编排式与协调式的差异、补偿操作设计、隔离性问题与生产实践
4
分布式追踪:定位跨服务性能瓶颈
分布式系统深入 深入解析分布式追踪——OpenTelemetry 标准、Span 与 Trace 模型、采样策略与 Jaeger 工程实践
5
2PC 与 3PC:分布式事务的协议基础
分布式系统深入 深入解析两阶段提交与三阶段提交协议——原理、阻塞问题与工程实践中的改进方案






