微服务网关的流量治理需求
微服务架构中,API网关是所有外部请求的统一入口。限流防止流量洪峰击穿下游服务,熔断在依赖服务故障时快速失败避免雪崩。Spring Cloud Gateway + Sentinel是目前Java生态中最主流的网关流量治理方案,本文从生产实践角度拆解配置、自定义扩展和故障排查。
Sentinel网关限流配置
Sentinel为Spring Cloud Gateway提供了专用模块sentinel-spring-cloud-gateway-adapter,支持按路由ID或API分组限流:
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.8</version>
</dependency>
配置限流规则:
@Configuration
public class GatewayConfig {
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
// 按路由ID限流:用户服务QPS上限500
rules.add(new GatewayFlowRule("user-service")
.setCount(500)
.setIntervalSec(1)
);
// 按路由+参数限流:单个IP每秒最多50次
rules.add(new GatewayFlowRule("user-service")
.setCount(50)
.setIntervalSec(1)
.setParamItem(new GatewayParamItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_IP)
)
);
// 订单服务突发限流:允许短暂突发
rules.add(new GatewayFlowRule("order-service")
.setCount(200)
.setIntervalSec(1)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
.setMaxQueueingTimeoutMs(500) // 排队等待500ms
);
GatewayRuleManager.loadRules(rules);
}
}
限流触发时默认返回429,自定义响应:
@Configuration
public class GatewayBlockHandler {
@PostConstruct
public void initBlockHandler() {
GatewayCallbackManager.setBlockHandler((exchange, t) -> {
Map<String, Object> result = Map.of(
"code", 429,
"message", "请求过于频繁,请稍后重试",
"timestamp", System.currentTimeMillis()
);
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(result));
});
}
}
Sentinel熔断降级配置
熔断针对下游服务的异常响应。三种熔断策略:
// 慢调用比例熔断
DegradeRule slowCallRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(1.0) // 慢调用阈值:1秒
.setSlowRatioThreshold(0.6) // 慢调用比例60%触发熔断
.setTimeWindow(30) // 熔断持续30秒
.setMinRequestAmount(10) // 最小请求数
.setStatIntervalMs(10000); // 统计窗口10秒
// 异常比例熔断
DegradeRule errorRatioRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.5) // 异常比例50%触发
.setTimeWindow(20)
.setMinRequestAmount(5)
.setStatIntervalMs(5000);
// 异常数熔断
DegradeRule errorCountRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.ERROR_COUNT.getType())
.setCount(10) // 10次异常触发
.setTimeWindow(60)
.setMinRequestAmount(5)
.setStatIntervalMs(10000);
DegradeRuleManager.loadRules(
Arrays.asList(slowCallRule, errorRatioRule, errorCountRule)
);
自定义过滤器链:请求日志与链路追踪
网关过滤器链是实现横切关注点的核心机制。一个生产级的请求日志过滤器:
@Component
public class RequestLogFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(RequestLogFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String traceId = UUID.randomUUID().toString().replace("-", "");
long startTime = System.currentTimeMillis();
// 注入traceId到请求头,传递到下游
ServerWebExchange mutatedExchange = exchange.mutate()
.request(builder -> builder.headers(headers -> {
headers.add("X-Trace-Id", traceId);
}))
.build();
// 存储开始时间,用于响应后计算耗时
mutatedExchange.getAttributes().put("startTime", startTime);
return chain.filter(mutatedExchange)
.doFinally(signalType -> {
Long endTime = System.currentTimeMillis();
Long duration = endTime - startTime;
String path = exchange.getRequest().getURI().getPath();
int status = exchange.getResponse().getStatusCode().value();
log.info("traceId={}, path={}, status={}, duration={}ms",
traceId, path, status, duration);
// 超过阈值告警
if (duration > 3000) {
log.warn("SLOW_REQUEST traceId={}, path={}, duration={}ms",
traceId, path, duration);
}
});
}
@Override
public int getOrder() {
return -1; // 最高优先级
}
}
动态路由与规则热更新
生产环境中限流规则需要动态调整,重启网关不可接受。Sentinel支持通过DataSource接入配置中心:
// Nacos数据源配置
@Bean
public ReadableDataSource<String, Set<GatewayFlowRule>> nacosGatewayRuleDataSource() {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "nacos-cluster:8848");
properties.put(PropertyKeyConst.NAMESPACE, "production");
ReadableDataSource<String, Set<GatewayFlowRule>> nacosDs =
new NacosDataSource<>(properties,
"gateway-group",
"gateway-flow-rules",
source -> JSON.parseObject(source,
new TypeReference<Set<GatewayFlowRule>>(){}.getType())
);
GatewayRuleManager.register2Property(nacosDs.getProperty());
return nacosDs;
}
在Nacos控制台修改规则后,Sentinel在1-2秒内自动拉取并生效,无需重启。同样的方式适用于降级规则和系统保护规则。
网关层故障排查手册
常见问题及处理:
# 1. 限流误触发(正常流量被429)
# 检查:Sentinel Dashboard → 簇点链路 → 实时监控
# 原因:QPS统计窗口默认1秒,瞬时脉冲可能触发
# 方案:调大intervalSec或切换为匀速排队模式
# 2. 熔断后不恢复
# 检查:DegradeRule的timeWindow配置
# 原因:timeWindow设太长,半开状态探活不够
# 方案:timeWindow设为15-30秒,配合minRequestAmount=3
# 3. 路由匹配不生效
# 检查:Gateway路由优先级(order值越小优先级越高)
# 原因:通配路由抢占了精确路由
# 方案:给精确路由设置更小的order值
微服务网关的流量治理是分布式系统稳定性的第一道屏障。限流规则的设计需要区分全局阈值和单维度阈值,熔断策略需要根据下游服务的SLA差异化配置,自定义过滤器链要控制好优先级和异常边界。所有规则都应该接入配置中心实现热更新,才能在线上快速响应流量变化。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springcloud-wei-fu-wu-wang-guan-xian-liu-rong-duan-shi-zhan/