Sentinel学习笔记
胜败兵家事不期,包羞忍耻是男儿。
Sentinel
springcloud依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
下面这个例子就是一个最简单的使用 Sentinel 的例子:
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
@RestController
public class TestController {
@Autowired
private TestService service;
@GetMapping(value = "/hello/{name}")
public String apiHello(@PathVariable String name) {
return service.sayHello(name);
}
}
@SentinelResource
注解用来标识资源是否被限流、降级。上述例子上该注解的属性 sayHello
表示资源名。
@SentinelResource
还提供了其它额外的属性如 blockHandler
,blockHandlerClass
,fallback
用于表示限流或降级的操作(注意有方法签名要求),更多内容可以参考 Sentinel 注解支持文档。若不配置 blockHandler
、fallback
等函数,则被流控降级时方法会直接抛出对应的 BlockException;若方法未定义 throws BlockException
则会被 JVM 包装一层 UndeclaredThrowableException
。
注:一般推荐将
@SentinelResource
注解加到服务实现上,而在 Web 层直接使用 Spring Cloud Alibaba 自带的 Web 埋点适配。Sentinel Web 适配同样支持配置自定义流控处理逻辑,参考 相关文档。
以上例子都是在 Web Servlet 环境下使用的。Sentinel 目前已经支持 Spring WebFlux,需要配合 spring-boot-starter-webflux
依赖触发 sentinel-starter 中 WebFlux 相关的自动化配置。
@RestController
public class TestController {
@GetMapping("/mono")
public Mono<String> mono() {
return Mono.just("simple string");
}
}
当 Spring WebFlux 应用接入 Sentinel starter 后,所有的 URL 就自动成为 Sentinel 中的埋点资源,可以针对某个 URL 进行流控。
Sentinel 控制台
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
注意: 集群资源汇总仅支持 500 台以下的应用集群,有大概 1 - 2 秒的延时。
Figure 1. Sentinel Dashboard
开启该功能需要3个步骤:
获取控制台
您可以从 release 页面 下载最新版本的控制台 jar 包。
您也可以从最新版本的源码自行构建 Sentinel 控制台:
- 下载 控制台 工程
- 使用以下命令将代码打包成一个 fat jar:
mvn clean package
启动控制台
Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
如若8080端口冲突,可使用 -Dserver.port=新端口
进行设置。
配置控制台信息
application.yml
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
这里的 spring.cloud.sentinel.transport.port
端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
更多 Sentinel 控制台的使用及问题参考: Sentinel 控制台文档 以及 Sentinel FAQ
注解埋点支持
Sentinel 提供了 @SentinelResource
注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException
等。使用 Sentinel Annotation AspectJ Extension 的时候需要引入以下依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>x.y.z</version>
</dependency>
@SentinelResource 注解
注意:注解方式埋点不支持 private 方法。
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource
注解包含以下属性:
-
value
:资源名称,必需项(不能为空) -
entryType
:entry 类型,可选项(默认为EntryType.OUT
) -
blockHandler
/blockHandlerClass
:blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。 -
fallback
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要和原函数一致,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。 - fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。 - defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要为空,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。 - defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
-
exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
注:1.6.0 之前的版本 fallback 函数只针对降级异常(
DegradeException
)进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException
时只会进入 blockHandler
处理逻辑。若未配置 blockHandler
、fallback
和 defaultFallback
,则被限流降级时会将 BlockException
直接抛出。
示例:
public class TestService {
// 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 static 函数.
@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
public void test() {
System.out.println("Test");
}
// 原函数
@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;
}
}
从 1.4.0 版本开始,注解方式定义资源支持自动统计业务异常,无需手动调用 Tracer.trace(ex)
来记录业务异常。Sentinel 1.4.0 以前的版本需要自行调用 Tracer.trace(ex)
来记录业务异常。
配置
AspectJ
若您的应用直接使用了 AspectJ,那么您需要在 aop.xml
文件中引入对应的 Aspect:
<aspects>
<aspect name="com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect"/>
</aspects>
Spring AOP
若您的应用使用了 Spring AOP,您需要通过配置的方式将 SentinelResourceAspect
注册为一个 Spring Bean:
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
我们提供了 Spring AOP 的示例,可以参见 sentinel-demo-annotation-spring-aop。er/sentinel-demo/sentinel-demo-annotation-spring-aop)。
Feign 支持
Sentinel 适配了 Feign 组件。如果想使用,除了引入 spring-cloud-starter-alibaba-sentinel
的依赖外还需要 2 个步骤:
- 配置文件打开 Sentinel 对 Feign 的支持:
feign.sentinel.enabled=true
- 加入
spring-cloud-starter-openfeign
依赖使 Sentinel starter 中的自动化配置类生效:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
这是一个 FeignClient
的简单使用示例:
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
Note | Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl。@FeignClient 注解中的所有属性,Sentinel 都做了兼容。 |
---|---|
EchoService
接口中方法 echo
对应的资源名为 GET:http://service-provider/echo/{str}
。
RestTemplate 支持
Spring Cloud Alibaba Sentinel 支持对 RestTemplate
的服务调用使用 Sentinel 进行保护,在构造 RestTemplate
bean的时候需要加上 @SentinelRestTemplate
注解。
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
@SentinelRestTemplate
注解的属性支持限流(blockHandler
, blockHandlerClass
)和降级(fallback
, fallbackClass
)的处理。
其中 blockHandler
或 fallback
属性对应的方法必须是对应 blockHandlerClass
或 fallbackClass
属性中的静态方法。
该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor
方法一致,其中参数多出了一个 BlockException
参数用于获取 Sentinel 捕获的异常。
比如上述 @SentinelRestTemplate
注解中 ExceptionUtil
的 handleException
属性对应的方法声明如下:
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
Note | 应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常 |
---|---|
@SentinelRestTemplate
注解的限流(blockHandler
, blockHandlerClass
)和降级(fallback
, fallbackClass
)属性不强制填写。
当使用 RestTemplate
调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel
信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse
用于构造返回信息。
Sentinel RestTemplate 限流的资源规则提供两种粒度:
-
httpmethod:schema://host:port/path
:协议、主机、端口和路径 -
httpmethod:schema://host:port
:协议、主机和端口
Note | 以 https://www.taobao.com/test 这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 GET:https://www.taobao.com 以及 GET:https://www.taobao.com/test
|
---|---|
动态数据源支持
SentinelProperties
内部提供了 TreeMap
类型的 datasource
属性用于配置数据源信息。
比如配置 4 个数据源:
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
#spring.cloud.sentinel.datasource.ds1.file.converter-class=com.alibaba.cloud.examples.JsonFlowRuleListConverter
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel
spring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
spring.cloud.sentinel.datasource.ds4.apollo.rule-type=param-flow
这种配置方式参考了 Spring Cloud Stream Binder 的配置,内部使用了 TreeMap
进行存储,comparator 为 String.CASE_INSENSITIVE_ORDER
。
Note | d1, ds2, ds3, ds4 是 ReadableDataSource 的名字,可随意编写。后面的 file ,zk ,nacos , apollo 就是对应具体的数据源,它们后面的配置就是这些具体数据源各自的配置。注意数据源的依赖要单独引入(比如 sentinel-datasource-nacos )。 |
---|---|
每种数据源都有两个共同的配置项: data-type
、 converter-class
以及 rule-type
。
data-type
配置项表示 Converter
类型,Spring Cloud Alibaba Sentinel 默认提供两种内置的值,分别是 json
和 xml
(不填默认是json)。 如果不想使用内置的 json
或 xml
这两种 Converter
,可以填写 custom
表示自定义 Converter
,然后再配置 converter-class
配置项,该配置项需要写类的全路径名(比如 spring.cloud.sentinel.datasource.ds1.file.converter-class=com.alibaba.cloud.examples.JsonFlowRuleListConverter
)。
rule-type
配置表示该数据源中的规则属于哪种类型的规则(flow
, degrade
, authority
, system
, param-flow
, gw-flow
, gw-api-group
)。注意网关流控规则 (GatewayFlowRule) 对应 gw-flow
。
Note | 当某个数据源规则信息加载失败的情况下,不会影响应用的启动,会在日志中打印出错误信息。 |
---|---|
Note | 默认情况下,xml 格式是不支持的。需要添加 jackson-dataformat-xml 依赖后才会自动生效。 |
---|---|
Note | 如果规则加载没有生效,有可能是 jdk 版本导致的,请关注 759 issue 的处理。 |
---|---|
关于 Sentinel 动态数据源的实现原理,参考: 动态规则扩展
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>
同时请将 spring.cloud.sentinel.filter.enabled
配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。如需细化到 URL 粒度,请参考 网关流控文档 自定义 API 分组。
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.sentinel.filter.enabled
配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。如需细化到 URL 粒度,请参考 网关流控文档 自定义 API 分组。
注意:网关流控规则数据源类型是 gw-flow
,若将网关流控规则数据源指定为 flow 则不生效。
Endpoint 支持
在使用 Endpoint 特性之前需要在 Maven 中添加 spring-boot-starter-actuator
依赖,并在配置中允许 Endpoints 的访问。
- Spring Boot 1.x 中添加配置
management.security.enabled=false
。暴露的 endpoint 路径为/sentinel
- Spring Boot 2.x 中添加配置
management.endpoints.web.exposure.include=*
。暴露的 endpoint 路径为/actuator/sentinel
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
配置
下表显示当应用的 ApplicationContext
中存在对应的Bean的类型时,会进行自动化设置:
存在Bean的类型 | 操作 | 作用 |
---|---|---|
UrlCleaner |
WebCallbackManager.setUrlCleaner(urlCleaner) |
资源清理(资源(比如将满足 /foo/:id 的 URL 都归到 /foo/* 资源下)) |
UrlBlockHandler |
WebCallbackManager.setUrlBlockHandler(urlBlockHandler) |
自定义限流处理逻辑 |
RequestOriginParser |
WebCallbackManager.setRequestOriginParser(requestOriginParser) |
设置来源信息 |
Spring Cloud Alibaba Sentinel 提供了这些配置选项:
配置项 | 含义 | 默认值 |
---|---|---|
spring.application.name or project.name
|
Sentinel项目名 | |
spring.cloud.sentinel.enabled |
Sentinel自动化配置是否生效 | true |
spring.cloud.sentinel.eager |
是否提前触发 Sentinel 初始化 | false |
spring.cloud.sentinel.transport.port |
应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer | 8719 |
spring.cloud.sentinel.transport.dashboard |
Sentinel 控制台地址 | |
spring.cloud.sentinel.transport.heartbeat-interval-ms |
应用与Sentinel控制台的心跳间隔时间 | |
spring.cloud.sentinel.transport.client-ip |
此配置的客户端IP将被注册到 Sentinel Server 端 | |
spring.cloud.sentinel.filter.order |
Servlet Filter的加载顺序。Starter内部会构造这个filter | Integer.MIN_VALUE |
spring.cloud.sentinel.filter.url-patterns |
数据类型是数组。表示Servlet Filter的url pattern集合 | /* |
spring.cloud.sentinel.filter.enabled |
Enable to instance CommonFilter | true |
spring.cloud.sentinel.metric.charset |
metric文件字符集 | UTF-8 |
spring.cloud.sentinel.metric.file-single-size |
Sentinel metric 单个文件的大小 | |
spring.cloud.sentinel.metric.file-total-count |
Sentinel metric 总文件数量 | |
spring.cloud.sentinel.log.dir |
Sentinel 日志文件所在的目录 | |
spring.cloud.sentinel.log.switch-pid |
Sentinel 日志文件名是否需要带上 pid | false |
spring.cloud.sentinel.servlet.block-page |
自定义的跳转 URL,当请求被限流时会自动跳转至设定好的 URL | |
spring.cloud.sentinel.flow.cold-factor |
WarmUp 模式中的 冷启动因子 | 3 |
spring.cloud.sentinel.zuul.order.pre |
SentinelZuulPreFilter 的 order | 10000 |
spring.cloud.sentinel.zuul.order.post |
SentinelZuulPostFilter 的 order | 1000 |
spring.cloud.sentinel.zuul.order.error |
SentinelZuulErrorFilter 的 order | -1 |
spring.cloud.sentinel.scg.fallback.mode |
Spring Cloud Gateway 流控处理逻辑 (选择 redirect or response ) |
|
spring.cloud.sentinel.scg.fallback.redirect |
Spring Cloud Gateway 响应模式为 ‘redirect’ 模式对应的重定向 URL | |
spring.cloud.sentinel.scg.fallback.response-body |
Spring Cloud Gateway 响应模式为 ‘response’ 模式对应的响应内容 | |
spring.cloud.sentinel.scg.fallback.response-status |
Spring Cloud Gateway 响应模式为 ‘response’ 模式对应的响应码 | 429 |
spring.cloud.sentinel.scg.fallback.content-type |
Spring Cloud Gateway 响应模式为 ‘response’ 模式对应的 content-type | application/json |
Note | 请注意。这些配置只有在 Servlet 环境下才会生效,RestTemplate 和 Feign 针对这些配置都无法生效 |
---|---|
自定义配置限流/流控返回异常信息
代码方式:
@Configuration
public class SeckillBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
R error = R.error(BaseException.TOO_MANY_REQUESTS.getCode(),BaseException.TOO_MANY_REQUESTS.getMsg());
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.getWriter().write(JSONUtil.toJsonStr(error));
}
}
配置文件方式:
spring:
cloud:
sentinel:
scg:
fallback:
mode: response
content-type: application/json
response-status: 403
response-body: "{'code':10405,'msg':'Blocked by Sentinel: 服务器繁忙'}"
注册数据源
通常需要调用以下方法将数据源注册至指定的规则管理器中:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
若不希望手动注册数据源,可以借助 Sentinel 的 InitFunc
SPI 扩展接口。只需要实现自己的 InitFunc
接口,在 init
方法中编写注册数据源的逻辑。比如:
package com.test.init;
public class DataSourceInitFunc implements InitFunc {
@Override
public void init() throws Exception {
final String remoteAddress = "localhost";
final String groupId = "Sentinel:Demo";
final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
限流规则
流控模式
一、流控模式-直接
添加规则:
测试例子分析:
启动测试
点击 察看结果树
上面测试例子,到Sentinel控制台的实时监控可以看到
二、流控模式-关联
• *关联模式* :统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
• 使用场景 :比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争 抢数据库锁,产生竞争。业务需求是有限支付和更新订单的业务,因此当修改订 单业务触发阈值时,需要对查询订单业务限流。
当/write资源访问量触发阈值时,就会对*/read*资源限流,避免影响/write资源。
同类组件功能对比
Sentinel | Hystrix | resilience4j | |
---|---|---|---|
隔离策略 | 信号量隔离(并发控制) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于慢调用比例、异常比例、异常数 | 基于异常比例 | 基于异常比例、响应时间 |
实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于 RxJava) | Ring Bit Buffer |
动态规则配置 | 支持近十种动态数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
单机限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
集群流控 | 支持 | 不支持 | 不支持 |
流量整形 | 支持预热模式与匀速排队控制效果 | 不支持 | 简单的 Rate Limiter 模式 |
系统自适应保护 | 支持 | 不支持 | 不支持 |
热点识别/防护 | 支持 | 不支持 | 不支持 |
多语言支持 | Java/Go/C++ | Java | Java |
Service Mesh 支持 | 支持 Envoy/Istio | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台,可配置规则、实时监控、机器发现等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 |
案例
需求:
•在OrderController新建两个端点:/order/query和/order/update,无需实现业务
•配置流控规则,当/order/ update资源被访问的QPS超过5时,对/order/query请求限流
- 编写测试controller方法:
- 添加规则(想给谁限流,就给谁添加规则)
- 借助JMeter进行测试:
4. 去网页访问验证:
query被限流
-
总结: 满足下面条件可以使用关联模式
-
两个有竞争关系的资源
-
一个优先级较高,一个优先级较低(优先级高的触发阈值时(本案例的order),对优先级低的限流(本案例的query))
三、流控模式-链路
案例:
- 编写测试代码:
- 注意:
Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解
去配置文件里配置,关闭context,就可以让controller里的方法单独成为一个链路;不关闭context的话,controller里的方法都会默认进去sentinel默认的根链路里,这样就只有一条链路,无法流控链路模式
- 启动之后,并到网页里分别访问了/order/query和/order/save接口后
- 添加规则:(对query做限制,save没有做限制)
- 借助JMeter来测试:
启动测试
版权声明:如无特别声明,本站收集的文章归 HuaJi66/Others 所有。 如有侵权,请联系删除。
联系邮箱: GenshinTimeStamp@outlook.com
本文标题:《 Sentinel学习笔记 》
本文链接:/%E5%BE%AE%E6%9C%8D%E5%8A%A1/springcloud/%E9%94%A6%E5%9B%8A/sentinel.html