目录
Spring Cloud Alibaba专栏目录(点击进入…)
Spring Cloud Ailibaba Geteway与Zuul(服务网关)
Spring Cloud Gateway服务网关
Sentinel支持对Spring Cloud Gateway、Zuul等主流的API Gateway进行限流。
Sentinel 1.6.0引入了Sentinel API Gateway Adapter Common模块,此模块中包含:
①网关限流的规则
②自定义API的实体和管理逻辑
1.GatewayFlowRule:网关限流规则
针对API Gateway的场景定制的限流规则,可以针对不同route(路由)或自定义的API分组进行限流,支持针对请求中的参数、Header、来源IP等进行定制化的限流。
2.ApiDefinition:用户自定义的API定义分组
可以看做是一些URL匹配的组合。比如:可以定义一个API叫“my_api”,请求path模式为“/foo/*”和“/baz/*”的都归到my_api这个API分组下面。限流的时候可以针对这个自定义的API分组维度进行限流。
网关限流规则(GatewayFlowRule字段)
加载网关规则:
①:通过GatewayRuleManager.loadRules(rules)手动加载网关规则
②:通过GatewayRuleManager.register2Property(property)注册动态规则源动态推送(推荐)
字段 | 描述 |
---|---|
resource | 资源名称。可以是网关中的route名称或者用户自定义的API分组名称 |
resourceMode | 规则是针对API Gateway的route还是用户在Sentinel中定义的API分组。默认route。 ①route:RESOURCE_MODE_ROUTE_ID ②API分组:RESOURCE_MODE_CUSTOM_API_NAME |
grade | 限流指标维度,同限流规则的grade字段 |
count | 限流阈值 |
intervalSec | 统计时间窗口,单位是秒,默认是 1 秒 |
controlBehavior | 流量整形的控制效果,同限流规则的controlBehavior字段,目前支持快速失败和匀速排队两种模式,默认快速失败 |
burst | 应对突发请求时额外允许的请求数目 |
maxQueueingTimeoutMs | 匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效 |
paramItem | 参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。 |
paramItem其中的字段:
(1)parseStrategy
从请求中提取参数的策略。目前支持提取来源(四种模式):
①IP:PARAM_PARSE_STRATEGY_CLIENT_IP
②Host:PARAM_PARSE_STRATEGY_HOST
③任意Header:PARAM_PARSE_STRATEGY_HEADER
④任意URL参数:PARAM_PARSE_STRATEGY_URL_PARAM
(2)fieldName
若提取策略选择Header模式或URL参数模式,则需要指定对应的header名称或URL参数名称。
(3)pattern
参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控;若为空则统计该请求属性的所有值。(1.6.2)
(4)matchStrategy
参数值的匹配策略(1.6.2 版本开始支持)
目前支持:
①精确匹配:PARAM_MATCH_STRATEGY_EXACT
②子串匹配:PARAM_MATCH_STRATEGY_CONTAINS
③正则匹配:PARAM_MATCH_STRATEGY_REGEX
Spring Cloud Gateway
若想跟Sentinel Starter配合使用,需要加上spring-cloud-alibaba-sentinel-gateway依赖,同时需要添加spring-cloud-starter-gateway依赖来让spring-cloud-alibaba-sentinel-gateway模块里的Spring Cloud Gateway自动化配置类生效:
同时请将spring.cloud.sentinel.filter.enabled配置项置为false(若在网关流控控制台上看到了URL资源,就是此配置项没有置为false)。Sentinel网关流控默认的粒度是route维度以及自定义API 组维度,默认不支持URL粒度。
注意:网关流控规则数据源类型是gw-flow,若将网关流控规则数据源指定为flow则不生效。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
从1.6.0版本开始,Sentinel提供了Spring Cloud Gateway的适配模块,可以提供两种资源维度的限流:
(1)route维度:即在Spring配置文件中配置的路由条目,资源名为对应的route Id
(2)自定义API维度:用户可以利用Sentinel提供的API来自定义一些API分组
在Spring Cloud Gateway中配置了以下路由:
server:
port: 8090
spring:
application:
name: spring-cloud-gateway
cloud:
gateway:
enabled: true
discovery:
locator:
lower-case-service-id: true
routes:
# Add your routes here.
- id: product_route
uri: lb://product
predicates:
- Path=/product/**
- id: httpbin_route
uri: https://httpbin.org
predicates:
- Path=/httpbin/**
filters:
- RewritePath=/httpbin/(?<segment>.*), /$\{segment}
同时自定义了一些 API分组:
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("some_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/product/baz"));
add(new ApiPathPredicateItem().setPattern("/product/foo/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("another_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/ahas"));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
那么这里面的route ID(如 product_route)和API name(如some_customized_api)都会被标识为Sentinel的资源。
比如:访问网关的URL为http://localhost:8090/product/foo/22的时候,对应的统计会加到product_route和some_customized_api这两个资源上面,而 http://localhost:8090/httpbin/json 只会对应到 http bin_route资源上面。
注意:有的时候Spring Cloud Gateway会自己在route名称前面拼一个前缀,如 ReactiveCompositeDiscoveryClient_xxx这种。请观察簇点链路页面实际的资源名。
可以在 GatewayCallbackManager 注册回调进行定制:
setBlockHandler:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler。默认实现为 DefaultBlockRequestHandler,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException。
注意:Sentinel网关流控默认的粒度是route维度以及自定义API分组维度,默认不支持URL粒度。若通过Spring Cloud Alibaba接入,请将spring.cloud.sentinel.filter.enabled配置项置为 false(若在网关流控控制台上看到了URL资源,就是此配置项没有置为false)。
若使用Spring Cloud Alibaba Sentinel数据源模块,需要注意网关流控规则数据源类型是gw-flow,若将网关流控规则数据源指定为flow则不生效。
Spring Cloud Zuul
若想跟Sentinel Starter配合使用,需要加上spring-cloud-alibaba-sentinel-gateway依赖,同时需要添加spring-cloud-starter-netflix-zuul依赖来让spring-cloud-alibaba-sentinel-gateway模块里的Zuul自动化配置类生效:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>