文章目录
- 前言
- 一、准备
- 1. 引入库
- 2. 注册过滤器
- 3. 添加配置
- 4. 效果展示
- 二、基于网关的流控
- 1. 新增流控规则
- 2. 测试准备
- 3. 测试结果
- 总结
前言
Sentinel从1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
- route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
- 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
一、准备
1. 引入库
这里我引入了和sentinel-dashboard
控制台相同版本的网关层依赖包,
第二个starter
引入尽量和你的spring-cloud-alibaba
相同即可
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-spring-cloud-gateway-adapter -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2023.0.1.0</version>
</dependency>
2. 注册过滤器
package org.example.gateway.config;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;
import java.util.Collections;
import java.util.List;
/**
* Create by zjg on 2024/8/24
*/
public class SentinelConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public SentinelConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// Register the block exception handler for Spring Cloud Gateway.
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
}
3. 添加配置
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
4. 效果展示
首次加载的时候,我们需要发起一次请求,才能在界面上看到监控信息,因为 Sentinel 使用了 lazy load 策略。
二、基于网关的流控
通过上图大家可以清楚的看到,我们在请求了localhost:8888/provider/hello?a=1
接口之后出现了对应的服务。
1. 新增流控规则
本机嘛,阈值没必要那么高
2. 测试准备
我这里使用curl命令来进行http请求测试,生成一个脚本,发起6次请求
curl --location --request GET 'localhost:8888/provider/hello?a=1' --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGFpbXMiOnsidXNlcm5hbWUiOiJhZG1pbiJ9LCJpc3MiOiJhdXRoMCIsImV4cCI6MTcyNDU5MDMzOH0.hWebKIoGRWSRaayncuMtwH9UPDVr5gcvcCm7R1FlxNg'
3. 测试结果
大家可以看到前5次是正常的,到第6次就超过了我们设置的阈值,返回都没有,其实是后台报错了导致的,我准备对各个组件适配Sentinel,这种使用方式是不太友好的。
总结
回到顶部
我最开始的愿景是:网关作为流量的统一入口,在网关层面做统一的流控是最合适不过了。
但是看到了官方的这句话Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。若通过 Spring Cloud Alibaba 接入,请将 spring.cloud.sentinel.filter.enabled 配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。
自定义支持 URL 粒度,但是这样做的工作量是巨大且难以管理的,尤其是我们有众多接口服务的时候。
这时候Sentinel针对网关的整合只能先告一段落,暂时让各个组件整合Sentinel,各组件维护自己的流控和降级规则等等。