Spring Cloud Alibaba Sentinel 网关限流适配器:Zuul/SCG 的 ServiceId 与 API Path 双重流控实践
2026/9/19 5:58:52 网站建设 项目流程

Spring Cloud Alibaba Sentinel 网关限流适配器:Zuul/SCG 的 ServiceId 与 API Path 双重流控实践

【免费下载链接】spring-cloud-alibabaSpring Cloud Alibaba provides a one-stop solution for application development for the distributed solutions of Alibaba middleware.项目地址: https://gitcode.com/gh_mirrors/sp/spring-cloud-alibaba

导读

Spring Cloud Alibaba 提供spring-cloud-alibaba-sentinel-gateway适配器模块,为微服务网关(Zuul 1 及 Spring Cloud Gateway)接入 Sentinel 流控能力,实现ServiceId 级API Path 级的精细流量控制。本文以该模块的官方 README(spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/README.md)为主线,结合仓库内实际源码,讲透接入步骤、过滤器工作原理、资源树结构、Dashboard 集成、数据源规则配置,以及 Fallback、RequestOriginParser、UrlCleaner 三类扩展点的自定义方式,帮助你直接在自己项目中落地网关级限流。

一、为什么网关需要 Sentinel 限流

在 Spring Cloud 生态中,Zuul 网关本身不提供限流(rateLimit)能力。若使用默认的SentinelRibbonFilter路由过滤器,请求会被 Hystrix Command 包装,而 Hystrix 只能提供服务级别的熔断保护,无法针对路由/接口做更细粒度的流控。

Sentinel 则可以针对 Spring Cloud Zuul 网关服务提供两层维度的流控:

  • ServiceId 级:按路由目标服务(如bookcoke)维度统计与限流;
  • API Path 级:按具体接口路径(如/book/uri中的/uri)维度统计与限流。

注意:该 README 描述的适配器面向Zuul 1(基于 Servlet 的阻塞式网关)。

二、快速接入:依赖与配置

1. 添加 Maven 依赖

在你的网关工程中引入:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> <version>x.y.z</version> </dependency>

该依赖由本仓库的 spring-cloud-alibaba-sentinel-gateway/pom.xml 构建产出,其内部聚合了sentinel-api-gateway-adapter-commonsentinel-parameter-flow-control以及spring-cloud-alibaba-sentinel-datasource等关键依赖,因此引入这一个坐标即可获得网关适配与规则数据源转换能力。

2. 开启 Zuul 适配器

application.properties/application.yml中开启:

# 默认值为 false,必须显式开启 spring.cloud.sentinel.zuul.enabled=true

三、工作原理:围绕 route Filter 的三个 Sentinel 过滤器

由于 Zuul 采用每线程连接阻塞模型(per thread connection block model),Sentinel 通过在route Filter前后追加过滤器来埋点统计,具体由三个 Zuul Filter 协作完成:

过滤器职责
SentinelPreFilter获取资源(resource)的 Entry,资源优先级为ServiceId,其次API Path
SentinelPostFilter响应成功后,退出 Entry(记录成功退出,释放统计槽位);
SentinelErrorFilter捕获到Exception时,记录异常并退出上下文(Context)。

过滤器顺序可配置

三个过滤器的执行顺序可通过配置调整:

spring.cloud.sentinel.zuul.order.post=0 spring.cloud.sentinel.zuul.order.pre=10000 spring.cloud.sentinel.zuul.order.error=-1

按上述示例,error过滤器最先执行(-1),post次之(0),pre最后(10000),开发者可根据自身网关过滤链的编排需求灵活覆盖。

生成的资源树结构

接入后,Sentinel 会在入口节点(EntranceNode)下按“服务 → 路由 → 接口”的层级生成统计节点。以cokebook两个路由为例,资源树大致如下:

EntranceNode: machine-root(t:3 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |-EntranceNode: coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |--coke(t:2 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |---/coke/uri(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |-EntranceNode: sentinel_default_context(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |-EntranceNode: book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |--book(t:1 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0) |---/book/uri(t:0 pq:0 bq:0 tq:0 rt:0 prq:0 1mp:0 1mb:0 1mt:0)

解读要点:

  • bookcokeServiceId(路由的服务标识);
  • ---/book/uriAPI Path 级资源,其真实 URI 为/uri(即去除 ServiceId 前缀后的路径,这里经过了 UrlCleaner 的规整,见下文);
  • pq:0 bq:0 tq:0分别对应 pass(通过数)、block(拦截数)、total(总数)等统计指标,可直接在 Sentinel Dashboard 上查看。

源码佐证:Zuul 时代的SentinelPreFilter/SentinelPostFilter/SentinelErrorFilter是该适配器的核心,虽然它们随 Zuul 1 适配器演进,但“先 ServiceId、后 API Path”的取资源顺序在 Gateway 适配器中被同样继承。在 sentinel-spring-cloud-gateway-example 示例中可看到同一套资源体系在 Spring Cloud Gateway 上的落地。

四、与 Sentinel Dashboard 集成

启动 Sentinel Dashboard(Sentinel 官方控制台,默认端口 8080)后,网关应用通过spring.cloud.sentinel.transport.dashboard=ip:port将实时指标上报,即可在“簇点链路”中看到第三节展示的book/book/uri等节点,并直接在该界面为 ServiceId 或 API Path 配置流控、降级规则。规则配置完成后,Sentinel 客户端会定期拉取并实时生效。

五、规则配置与数据源

Sentinel 支持完整的动态规则配置体系(Dynamic Rule Configuration):可通过 API 直接推送规则,也可通过文件、Nacos、ZooKeeper、Apollo 等数据源动态加载。本仓库的spring-cloud-alibaba-sentinel-datasource模块提供了完整的数据源支持(见 spring-cloud-alibaba-sentinel-datasource 目录下的 21 个核心类),并且网关模块内置了 JSON/XML 规则转换器。

从 SentinelGatewayAutoConfiguration.java 可以看到,模块自动注册了 4 个规则转换器 Bean:

  • sentinel-json-gw-flow-converter:将 JSON 反序列化为GatewayFlowRule(网关流控规则);
  • sentinel-json-gw-api-group-converter:将 JSON 反序列化为ApiDefinition(API 分组定义);
  • sentinel-xml-gw-flow-converter:XML 版本的流控规则转换器;
  • sentinel-xml-gw-api-group-converter:XML 版本的 API 分组转换器。

其中内置的ApiPredicateItemDeserializer支持对pattern(对应ApiPathPredicateItem,按路径匹配)与items(对应ApiPredicateGroupItem,按分组匹配)的多态反序列化,使 Nacos/文件等数据源中的 JSON/XML 规则能直接映射为 Sentinel 网关规则对象。

六、自定义 Fallback:SentinelFallbackProvider

当请求被 Sentinel 拦截(抛出BlockException)时,适配器会交给 Fallback Provider 生成降级响应。

  • 默认实现为DefaultBlockFallbackProvider
  • 你可以实现SentinelFallbackProvider接口定义自己的 Fallback Provider。

路由匹配规则:默认 Fallback 路由为ServiceId + URI PATH的拼接,例如/book/coke:其中第一个book是 ServiceId,/uri是 URI PATH,两者都参与匹配,因此自定义 Provider 时需按此约定返回getRoute()

自定义示例:

// custom provider public class MyCokeServiceBlockFallbackProvider implements SentinelFallbackProvider { private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class); // 可将 route 定义为服务级 @Override public String getRoute() { return "/coke/uri"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { if (cause instanceof BlockException) { logger.info("get in fallback block exception:{}", cause); return response(HttpStatus.TOO_MANY_REQUESTS, route); } else { return response(HttpStatus.INTERNAL_SERVER_ERROR, route); } } }

要点:

  • causeBlockException(触发流控/降级)时返回429 TOO_MANY_REQUESTS
  • 其他异常返回500 INTERNAL_SERVER_ERROR
  • response(...)方法需自行构造ClientHttpResponse,例如携带降级信息体返回给调用方。

Spring Cloud Gateway 场景的配置式 Fallback

若你使用的是 Spring Cloud Gateway(SCG),模块还提供了配置式 Fallback,无需写 Java 代码。对应配置前缀为spring.cloud.sentinel.scg(见 ConfigConstants.java 中的GATEWAY_PREFIX),属性类为 SentinelGatewayProperties.java:

配置项说明默认值
spring.cloud.sentinel.scg.fallback.mode降级模式:response(返回响应体)或redirect(重定向)
spring.cloud.sentinel.scg.fallback.redirectredirect模式下的重定向地址
spring.cloud.sentinel.scg.fallback.response-bodyresponse模式下的响应体内容
spring.cloud.sentinel.scg.fallback.response-statusresponse模式下的 HTTP 状态码429(TOO_MANY_REQUESTS)
spring.cloud.sentinel.scg.fallback.content-typeresponse模式下的 Content-Typeapplication/json
spring.cloud.sentinel.scg.orderSentinelGatewayFilter的过滤器顺序Ordered.HIGHEST_PRECEDENCE(最高优先级)

上述默认值均有源码与单测依据:默认状态码与 Content-Type 定义在 FallbackProperties.java 中,并由 FallbackPropertiesTest.java 的testDefaultValues用例验证。而 SentinelSCGAutoConfiguration.java 的initFallback()方法会在mode=response时通过GatewayCallbackManager.setBlockHandler(...)注册匿名响应处理器,在mode=redirect时注册RedirectBlockRequestHandler;对应行为由 SentinelSCGAutoConfigurationTest.java 的testInitWithFallbackMsgResponsetestInitWithFallbackRedirect两个用例覆盖验证。

七、自定义 Request Origin Parser

Sentinel 支持“调用来源(origin)”维度限流。默认情况下适配器使用DefaultRequestOriginParser解析 origin,你可以实现RequestOriginParser接口按业务需要自定义解析逻辑:

public class CustomRequestOriginParser implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { // do custom logic. 例如按 header、IP、token 等解析调用来源 return ""; } }

将自定义实现注册为 Spring Bean 后,即可在流控规则中按来源做差异化限流(例如区分内部调用与外部调用)。

八、自定义 UrlCleaner

默认情况下适配器使用DefaultUrlCleaner定义 URI 资源。它负责把形如/book/uri的原始请求路径“清洗”成统一的资源名(例如去掉带参数后缀、归一化数字 ID 等),避免每条动态路径都被当作独立资源。实现UrlCleaner接口即可自定义:

public class CustomUrlCleaner implements UrlCleaner { @Override public String clean(String originUrl) { // do custom logic. 例如将 /order/{id} 归一到 /order/* return originUrl; } }

合理清洗后,API Path 级限流才能稳定命中聚合资源;这也解释了第三节资源树中/book/uri是规整后的真实 URI。

九、从 Zuul 1 到 Spring Cloud Gateway:模块的现状与示例

需要说明的是,随着 Spring Cloud 官方逐步进入 Gateway 时代,本模块的源码重心也迁移到了 Spring Cloud Gateway(SCG)适配上。从 spring-cloud-alibaba-sentinel-gateway/src/main 目录可以观察到清晰的包结构:

  • scg/包:Spring Cloud Gateway 适配,核心类为SentinelSCGAutoConfigurationSentinelGatewayProperties
  • 根包:SentinelGatewayAutoConfiguration(规则转换器)、GatewayEnvironmentPostProcessorFallbackPropertiesConfigConstants

SCG 适配会自动完成三件事:

  1. 注册SentinelGatewayFilter(默认@Order(-1),可通过spring.cloud.sentinel.scg.order调整),对每条路由请求埋点统计;
  2. 注册SentinelGatewayBlockExceptionHandler@Order(HIGHEST_PRECEDENCE)),统一处理被拦截的请求;
  3. 通过GatewayEnvironmentPostProcessorspring.cloud.sentinel.filter.enabled默认置为false(见 GatewayEnvironmentPostProcessor.java),避免普通 Servlet 过滤器与网关过滤器双重埋点。

仓库内配套的实战示例可直接参考:

  • sentinel-spring-cloud-gateway-example:Spring Cloud Gateway + Sentinel 网关限流示例;
  • nacos-gateway-example:结合 Nacos 服务发现与网关路由的示例。

结语

spring-cloud-alibaba-sentinel-gateway让网关在“服务级熔断”之外补上了“路由/接口级流控”的能力:Zuul 1 场景通过三个过滤器完成埋点,Spring Cloud Gateway 场景通过自动配置的SentinelGatewayFilter完成同样的资源统计。结合本仓库源码,你可以清晰看到资源树如何按 ServiceId → API Path 分层、规则如何通过 JSON/XML 转换器从数据源加载,以及 Fallback、Origin 解析、UrlCleaner 三大扩展点如何按需定制。建议按此文档顺序:先接入依赖并开启开关,再在 Dashboard 中观察簇点链路,最后按业务诉求逐个实现自定义扩展。

【免费下载链接】spring-cloud-alibabaSpring Cloud Alibaba provides a one-stop solution for application development for the distributed solutions of Alibaba middleware.项目地址: https://gitcode.com/gh_mirrors/sp/spring-cloud-alibaba

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询