微服务架构下,API网关承担流量入口职责,限流熔断是保障系统高可用设计的核心机制。Spring Cloud Gateway作为Spring生态推荐的网关组件,集成Sentinel可实现路由级限流、服务熔断降级和规则动态推送。本文从集成配置到规则持久化,给出生产环境落地的完整方案。
Spring Cloud Gateway集成Sentinel基础配置
Spring Cloud Gateway 4.x与Sentinel 1.8.x的集成通过spring-cloud-starter-alibaba-sentinel-gateway模块完成。Sentinel为Gateway提供自定义SlotChain,在路由转发前执行限流判断。
<!-- pom.xml 依赖配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel-gateway</artifactId>
<version>2023.0.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.8</version>
</dependency>
# application.yml
server:
port: 8080
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: RequestSize
args:
maxSize: 10MB
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
backoff:
firstBackoff: 100ms
maxBackoff: 500ms
factor: 2
sentinel:
transport:
dashboard: 127.0.0.1:8858
port: 8719
eager: true # 网关启动即初始化Sentinel
filter:
enabled: false # 关闭默认WebFilter,使用Gateway专用Slot
eager=true确保网关启动时立即与Sentinel Dashboard建立连接,避免首批请求未被监控。filter.enabled=false关闭Sentinel默认的Web MVC过滤器,因为Gateway基于Reactor而非Servlet,需要使用Gateway专用的限流入口。
路由级限流规则配置与自定义异常响应
Sentinel Gateway适配器自动将每个路由ID注册为资源。限流规则可直接针对路由ID配置,也可通过自定义API分组聚合多个路由。QPS超限后默认返回429状态码,生产环境需要自定义错误响应体。
@Configuration
public class GatewayConfig {
@PostConstruct
public void init() {
// 自定义限流异常处理器
GatewayCallbackManager.setBlockHandler((exchange, ex) -> {
Map<String, Object> result = new HashMap<>();
result.put("code", 429);
result.put("message", "请求过于频繁,请稍后重试");
result.put("timestamp", System.currentTimeMillis());
result.put("path", exchange.getRequest().getPath().value());
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(result));
});
// 自定义API分组(跨路由限流)
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api = new ApiDefinition("payment-api")
.setPredicateItems(Collections.singleton(
new ApiPathPredicateItem()
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)
.setPattern("/api/payment/")
));
definitions.add(api);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
}
// 动态添加限流规则
public class FlowRuleManager {
public static void addRouteFlowRule(String routeId, int count) {
Set<FlowRule> rules = new HashSet<>();
FlowRule rule = new FlowRule(routeId);
rule.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(count); // QPS阈值
rule.setLimitApp("default");
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
rules.add(rule);
GatewayFlowRuleManager.loadRules(rules);
}
public static void addParamFlowRule(String routeId, String paramName, int count) {
// 基于请求参数限流(如按userId限流)
GatewayParamFlowRule rule = new GatewayParamFlowRule(routeId)
.setParamIdx(0) // 参数索引
.setCount(count)
.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 从请求头提取参数
rule.setParamItem(
new GatewayParamFlowRule.ParamItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
.setFieldName("X-User-Id")
);
Set<GatewayParamFlowRule> rules = new HashSet<>();
rules.add(rule);
GatewayParamFlowRuleManager.loadRules(rules);
}
}
服务熔断降级规则与慢调用比例策略
限流保护网关自身,熔断保护下游服务。Sentinel支持RT(响应时间)和异常比例两种熔断策略。慢调用比例策略在指定窗口内慢调用占比超过阈值时触发熔断,适合对延迟敏感的场景。
public class DegradeRuleConfig {
public static void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
// 慢调用比例熔断
DegradeRule slowCallRule = new DegradeRule("order-service")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(500) // 慢调用阈值:500ms
.setSlowRatioThreshold(0.6) // 慢调用比例阈值:60%
.setMinRequestAmount(5) // 最小请求数
.setStatIntervalMs(10000) // 统计窗口:10秒
.setTimeWindow(10); // 熔断持续时间:10秒
rules.add(slowCallRule);
// 异常比例熔断
DegradeRule exceptionRule = new DegradeRule("order-service")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.5) // 异常比例阈值:50%
.setMinRequestAmount(10)
.setStatIntervalMs(10000)
.setTimeWindow(15);
rules.add(exceptionRule);
// 异常数熔断
DegradeRule exceptionCountRule = new DegradeRule("payment-service")
.setGrade(CircuitBreakerStrategy.ERROR_COUNT.getType())
.setCount(20) // 异常数阈值:20
.setMinRequestAmount(20)
.setStatIntervalMs(60000)
.setTimeWindow(30);
rules.add(exceptionCountRule);
DegradeRuleManager.loadRules(rules);
}
}
熔断触发后的降级处理通过Gateway的fallback机制实现。被熔断的服务请求返回预设的降级响应,而非直接报错。
@Configuration
public class FallbackConfig {
@Bean
public RouterFunction<ServerResponse> fallbackRouter() {
return RouterFunctions.route()
.GET("/fallback/order", request ->
ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(Map.of(
"code", 503,
"message", "订单服务暂时不可用,请稍后重试",
"fallback", true
)))
)
.GET("/fallback/payment", request ->
ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(Map.of(
"code", 503,
"message", "支付服务降级中,请稍后重试",
"fallback", true
)))
)
.build();
}
}
// 路由配置中指定fallback URI
// application.yml
/*
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: CircuitBreaker
args:
name: orderCircuitBreaker
fallbackUri: forward:/fallback/order
*/
规则持久化方案:Nacos动态配置中心
Sentinel默认将规则存储在内存中,应用重启后规则丢失。生产环境必须将规则持久化到配置中心,Nacos是Spring Cloud Alibaba生态的推荐方案。规则变更通过Nacos配置监听实时推送到网关节点。
# application.yml Sentinel Nacos数据源配置
spring:
cloud:
sentinel:
datasource:
# 限流规则
flow:
nacos:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
namespace: ${NACOS_NAMESPACE:sentinel}
group-id: SENTINEL_GROUP
data-id: ${spring.application.name}-flow-rules.json
rule-type: flow
# 熔断规则
degrade:
nacos:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
namespace: ${NACOS_NAMESPACE:sentinel}
group-id: SENTINEL_GROUP
data-id: ${spring.application.name}-degrade-rules.json
rule-type: degrade
# 网关限流规则
gateway-flow:
nacos:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
namespace: ${NACOS_NAMESPACE:sentinel}
group-id: SENTINEL_GROUP
data-id: ${spring.application.name}-gateway-flow-rules.json
rule-type: gw-flow
Nacos中存储的限流规则JSON格式示例:
[
{
"resource": "user-service",
"resourceMode": 0,
"grade": 1,
"count": 500,
"intervalSec": 1,
"burst": 100,
"controlBehavior": 0,
"paramItem": null
},
{
"resource": "order-service",
"resourceMode": 0,
"grade": 1,
"count": 300,
"intervalSec": 1,
"burst": 50,
"controlBehavior": 2,
"maxQueueingTimeoutMs": 500,
"paramItem": null
}
]
controlBehavior=2表示匀速排队模式,请求在阈值内匀速通过,超出部分排队等待,适合突发流量削峰场景。maxQueueingTimeoutMs设置排队超时时间,超时请求被拒绝。
网关高可用部署与监控告警
网关作为流量入口自身也需要高可用保障。多实例部署配合负载均衡,通过Spring Boot Actuator暴露健康检查接口。Sentinel Dashboard提供实时监控面板,但生产环境建议接入Prometheus + Grafana做长期指标存储和告警。
# 暴露Sentinel指标到Prometheus
management:
endpoints:
web:
exposure:
include: health,info,prometheus,sentinel
metrics:
tags:
application: ${spring.application.name}
# Sentinel指标自定义
@Component
public class SentinelMetricsConfig {
@EventListener
public void onBlockEvent(BlockEvent event) {
Metrics.counter("sentinel.block.total",
"resource", event.getResourceName(),
"rule", event.getLimitApp(),
"type", event.getBlockType().name()
).increment();
}
@EventListener
public void onCircuitBreakerEvent(CircuitBreakerEvent event) {
Metrics.gauge("sentinel.circuit.state",
Tags.of("resource", event.getResourceName()),
event.getState().ordinal()
);
}
}
Grafana面板建议配置以下告警规则:网关5xx错误率超过1%、单路由QPS接近限流阈值80%、熔断器处于Open状态持续超过30秒。告警通过webhook推送到运维群,触发自动化扩容或限流阈值调整流程。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springcloudgateway-xian-liu-rong-duan-pei-zhi-sentinel-ji/