mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1299 字
3 分钟
API 网关:微服务的统一入口
2025-03-26

某社交平台在明星官宣瞬间涌入百万用户,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: 10

4.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: 转发请求(负载均衡)

网关需要处理以下场景:

  • 实例上线:更新路由表,新实例开始接收流量
  • 实例下线:移除路由表,请求不再转发到已下线实例
  • 实例异常:熔断器触发,暂时切断对该实例的请求

六、主流网关对比#

网关语言特点性能适用场景
KongLua插件丰富、生态完善企业级 API 管理
Spring Cloud GatewayJavaSpring 生态集成Spring Cloud 微服务
EnvoyC++服务网格原生极高Istio 数据平面
APISIXLua云原生、动态配置Kubernetes 环境
NginxC高性能、稳定极高反向代理、静态资源

七、网关性能优化#

优化项方法预期收益
连接池复用后端连接延迟降低 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

八、实践建议#

  1. 网关作为统一入口:所有外部请求必须经过网关,后端服务不直接暴露
  2. 限流算法选择:令牌桶适合 API 限流,漏桶适合流量整形
  3. 熔断器配置:根据业务 SLA 设置失败率阈值和超时时间
  4. 灰度发布:先小范围验证,再逐步放量
  5. 监控告警:网关是流量入口,必须配备完善的监控

API 网关解决了微服务架构中”南北向”流量(从外部进入集群)的管理问题。理解限流、熔断、灰度发布等核心机制,才能构建可靠的微服务入口。网关与服务发现、分布式追踪等组件紧密协作,共同构成微服务的基础设施层。

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

API 网关:微服务的统一入口
https://blog.souloss.com/posts/distributed/distributed-api-gateway/
作者
Souloss
发布于
2025-03-26
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时