4. API网关与流量控制:Nginx/Kong网关配置、限流算法(令牌桶、漏桶)、熔断降级策略

在信贷决策高并发评分系统中,API网关是流量的第一道防线。它负责统一接入、协议转换、身份认证、流量控制和熔断降级。本章聚焦于网关配置、限流算法原理与实现、以及熔断降级的实战策略。

4.1 网关选型与核心配置

生产环境中,Nginx和Kong是两种主流选择。Nginx轻量高效,适合作为反向代理和基础限流层;Kong基于OpenResty,提供插件化的流量管理、认证和监控能力。

特性 Nginx Kong
性能 极高,纯C实现 较高,基于Nginx + Lua
限流能力 内置 ngx_http_limit_req_module 插件 rate-limiting(支持本地/集群)
熔断降级 需结合 Lua 或第三方模块 插件 proxy-cache / 自定义插件
动态配置 需 reload 或借助 OpenResty 支持 Admin API 动态更新
适用场景 高并发静态限流、SSL终结 微服务网关、多租户限流

4.1.1 Nginx 限流配置示例

使用 limit_req_zone 和 limit_req 指令实现基于IP的令牌桶限流:

http {
    # 定义限流区域:每个IP 10MB空间,速率 5 req/s(漏桶模式)
    limit_req_zone $binary_remote_addr zone=scoring_api:10m rate=5r/s;

    server {
        listen 80;
        location /api/v1/score {
            # 突发容量 10,延迟处理(nodelay 则直接拒绝超限请求)
            limit_req zone=scoring_api burst=10 nodelay;
            proxy_pass http://backend_scoring;
        }
    }
}
生产建议: 将限流键从 $binary_remote_addr 改为 $http_x_forwarded_for 以支持CDN场景;burst 值建议根据压测结果设定,避免误杀正常流量。

4.1.2 Kong 限流插件配置

Kong 的 rate-limiting 插件支持秒/分/时/日维度,可配合 Redis 实现集群级精确限流:

# 通过 Admin API 启用限流
curl -X POST http://localhost:8001/services/scoring-service/plugins \
  --data "name=rate-limiting" \
  --data "config.second=10" \
  --data "config.minute=100" \
  --data "config.policy=redis" \
  --data "config.redis_host=redis-cluster.example.com"

4.2 限流算法:令牌桶与漏桶

两种算法在高并发评分系统中各有适用场景。下表对比其核心差异:

维度 令牌桶 (Token Bucket) 漏桶 (Leaky Bucket)
核心思想 以固定速率生成令牌,请求消耗令牌 以固定速率漏出请求,超出则丢弃
突发处理 允许短时突发(桶内令牌累积) 严格平滑,不允许突发
适用场景 评分接口允许短时流量尖峰 数据库写入、消息队列等需严格整形
实现复杂度 中等(需维护令牌计数器+定时器) 较低(队列+固定消费速率)
典型实现 Guava RateLimiter、Nginx limit_req 队列缓冲、Kong rate-limiting (policy=local)
令牌桶 vs 漏桶 限流流程对比 令牌桶算法 令牌生成器 (5 t/s) 令牌桶 (容量20) 当前令牌: 12 请求 消耗1令牌 放行 漏桶算法 请求 漏桶队列 (队列长度 10) 固定漏出 (5 r/s) 处理请求 丢弃

4.3 熔断降级策略

当评分服务下游(如征信机构、模型推理服务)出现超时或异常时,熔断机制可以快速切断流量,防止级联故障。降级则提供备选响应,保证核心链路可用。

4.3.1 熔断状态机

熔断器包含三个状态:关闭(正常调用)、打开(直接拒绝)、半开(试探恢复)。

熔断器状态机 关闭 (CLOSED) 正常调用 打开 (OPEN) 快速失败 半开 (HALF_OPEN) 试探恢复 失败率 > 阈值 超时后尝试 成功 失败

4.3.2 降级策略配置

在评分系统中,降级策略需要根据业务重要性分级:

降级等级 触发条件 降级行为 影响范围
L1 轻度 单次超时 > 500ms 返回缓存评分结果(T+1) 单个请求
L2 中度 连续5次超时或错误 返回默认评分(如600分) 当前用户会话
L3 严重 错误率 > 50% 持续10秒 返回“系统繁忙”提示,拒绝评分 全局限流

4.3.3 基于 Sentinel 的熔断降级实现

在 Java 微服务架构中,Sentinel 提供了声明式熔断降级能力:

@SentinelResource(
    value = "scoring",
    fallback = "scoringFallback",
    blockHandler = "scoringBlockHandler"
)
public ScoreResult getScore(ApplyRequest request) {
    // 调用征信模型
    return modelService.invoke(request);
}

// 降级方法:返回缓存或默认值
public ScoreResult scoringFallback(ApplyRequest request, Throwable t) {
    log.warn("scoring fallback, reason: {}", t.getMessage());
    return ScoreResult.fromCache(request.getUserId());
}

// 限流熔断后的 blockHandler
public ScoreResult scoringBlockHandler(ApplyRequest request, BlockException e) {
    log.warn("scoring blocked, reason: {}", e.getMessage());
    return ScoreResult.defaultScore();
}
注意: 降级方法必须与原方法在同一个类中,且参数列表需额外包含 Throwable 或 BlockException;生产环境建议将降级逻辑抽取到独立 Service,避免代码膨胀。

4.4 网关层流量控制最佳实践

  • 分层限流: 网关层(Nginx/Kong)做粗粒度限流(按IP/API),应用层(Sentinel/Resilience4j)做细粒度限流(按用户/产品)。
  • 动态配置: 使用配置中心(Apollo/Nacos)动态调整限流阈值,避免重启网关。
  • 监控告警: 对限流触发次数、熔断次数、降级比例设置告警,阈值建议:限流触发率 < 5%,熔断次数 < 10次/分钟。
  • 压测验证: 上线前使用 JMeter 或 Locust 模拟突发流量,验证限流和熔断是否按预期生效。
核心原则: 限流保护系统不被冲垮,熔断防止故障扩散,降级保证用户体验。三者配合使用,才能构建高可用的信贷评分网关。