赞
踩
Sentinel 的使用可以分为两个部分:
在客户端 Spring Boot 项目的pom.xml文件中添加Sentinel的依赖。
<!-- Sentinel 核心依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>最新版本号</version>
</dependency>
<!-- Spring Boot 集成 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>最新版本号</version>
</dependency>
Sentinel Dashboard是一个可视化的控制台,用于查看流量数据和管理规则。可以从GitHub上下载最新版本的控制台 jar 包再通过命令将其启动。或者也可以下载 Sentinel 控制台源码自行构建运行。
1.下载地址:
https://github.com/alibaba/Sentinel/releases
2.启动命令,-Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
3.启动成功后,在浏览器中输入 http://localhost:8080 打开控制台。
4.输入默认的用户名和密码都是 sentinel进行登录。
在客户端项目的application.properties或application.yml配置文件中设置Sentinel Dashboard的地址。
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
在客户端代码中,可以通过编程的方式调用 Sentinel 的 API 来定义资源。也可以通过@SentinelResource
注解对某个方法进行标注成资源。
(1)API 方式:
@GetMapping("/example")
public String example() {
// 定义资源名称
String resource = "example";
// 调用Sentinel API进行流量控制
SphU.entry(resource, () -> {
// 这里是你的业务逻辑
return "Hello Sentinel";
});
return "success";
}
(2)注解方式:
@SentinelResource(value = "productDetails", blockHandler = "blockHandler")
public ProductDetails getProductDetails(String productId) {
// 业务逻辑
}
在Sentinel Dashboard控制台中进行图形化配置规则。进入控制台后,选择左侧菜单栏的具体规则菜单,然后点击右上方"新增"按钮来定义规则。也可以通过编程方式动态添加GatewayFlowRule到Sentinel的规则仓库中。
(1)控制台图形化配置:
(2)编程式动态添加:
public class RuleConfig {
public static void main(String[] args) {
// 创建一个限流规则
FlowRule rule = new FlowRule();
rule.setResource("product_route"); // 设置资源名称
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 设置限流策略等级为QPS
rule.setCount(10); // 设置每秒最大请求数为10
// 将规则添加到内存中
GatewayRuleManager.loadRules(Collections.singletonList(rule));
}
}
通过@SentinelResource
注解将需要使用 Sentinel 进行控制的方法定义成资源,后续对该方法的访问都会受到Sentinel 所配置的相关规则控制。
@RestController public class TestController { @Autowired private TestService service; @GetMapping(value = "/hello/{name}") public String apiHello(@PathVariable String name) { return service.sayHello(name); } } @Service public class TestService { @SentinelResource(value = "sayHello") public String sayHello(String name) { return "Hello, " + name; } }
@SentinelResource
注解用来标识资源是否被限流、降级。该注解有如下属性:
示例:
public class TestService { // 原函数 @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback") public String hello(long s) { return String.format("Hello at %d", s); } // Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数. public String helloFallback(long s) { return String.format("Halooooo %d", s); } // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致. public String exceptionHandler(long s, BlockException ex) { // Do some log here. ex.printStackTrace(); return "Oops, error occurred at " + s; } }
若想让Spring Cloud Gateway 跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway
依赖,同时需要添加 spring-cloud-starter-gateway
依赖来让 spring-cloud-alibaba-sentinel-gateway
模块里的 Spring Cloud Gateway 自动化配置类生效。
<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>
在Spring Cloud Gateway中,SentinelGatewayFilter
作为一个全局过滤器被集成进来,用于拦截流经网关的请求,并应用Sentinel的流量控制规则。Sentinel 提供了 Spring Cloud Gateway 两种资源维度的限流,默认的粒度是 route 维度以及自定义 API 分组维度。默认不支持 URL 粒度,所以需要将 spring.cloud.sentinel.filter.enabled 配置项置为 false。
routeId
使用时首先需引入以下模块:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
然后再注入对应的 SentinelGatewayFilter
实例以及 SentinelGatewayBlockExceptionHandler
实例即可。
@Configuration public class GatewayConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public GatewayConfiguration(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(); } }
如果需要自定义流量控制逻辑,可以创建一个自定义的SentinelGatewayFilter
实现类。通常涉及以下步骤:
@EnableSentinel
注解来开启Sentinel。GlobalFilter
接口的类。这个接口用于定义过滤器的名称、描述和执行逻辑。SentinelGatewayFilter
:在你的自定义过滤器中注入SentinelGatewayFilter
,以便能够调用Sentinel的处理逻辑。GlobalFilter
实现类作为Bean注册到Spring应用上下文中。示例:
/** * 创建自定义过滤器 **/ @Component public class CustomSentinelGatewayFilter implements GlobalFilter, Ordered { private final SentinelGatewayFilter sentinelGatewayFilter; // 注入SentinelGatewayFilter public CustomSentinelGatewayFilter(SentinelGatewayFilter sentinelGatewayFilter) { this.sentinelGatewayFilter = sentinelGatewayFilter; } /** * 实现自定义过滤逻辑 **/ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { try { // 在执行Sentinel的过滤逻辑之前,可以添加自定义的预处理逻辑 // ... // 执行Sentinel的过滤逻辑 return sentinelGatewayFilter.filter(exchange, chain); } catch (BlockException ex) { // 当Sentinel拦截请求时,可以在这里添加自定义的处理逻辑 // ... return Mono.empty(); } } @Override public int getOrder() { // 设置过滤器的执行顺序,数值越小越先执行 return SentinelGatewayFilter.ORDER - 1; } }
在Spring Boot的配置类中注册自定义过滤器。
@Configuration
public class GatewayConfig {
@Bean
public GlobalFilter customFilter() {
return new CustomSentinelGatewayFilter(new SentinelGatewayFilter());
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。