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) |
4.3 熔断降级策略
当评分服务下游(如征信机构、模型推理服务)出现超时或异常时,熔断机制可以快速切断流量,防止级联故障。降级则提供备选响应,保证核心链路可用。
4.3.1 熔断状态机
熔断器包含三个状态:关闭(正常调用)、打开(直接拒绝)、半开(试探恢复)。
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 模拟突发流量,验证限流和熔断是否按预期生效。
核心原则: 限流保护系统不被冲垮,熔断防止故障扩散,降级保证用户体验。三者配合使用,才能构建高可用的信贷评分网关。