本文版本:spring-cloud-starter-alibaba:2.2.0.RELEASE

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_数据库


SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_sentinel_02

如下图所示,我们可以针对某个资源添加流控规则,流控模式有直接、关联和链路。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_链路_03

【1】直接

添加流控规则如下,阈值类型为QPS,单机阈值为1。表示1秒钟内查询1次就是OK,若超过次数1,就直接-快速失败,报默认错误。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_限流_04

浏览器频繁访问 :http://localhost:8401/testA ,将会抛出异常信息Blocked by Sentinel (flow limiting)。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_限流_05

需要说明的是,在未做持久化前,每次服务实例的重启都会清空流控规则。

【2】关联

当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。

比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。

可使用关联限流来避免具有关联关系的资源之间过度的争抢。举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 FlowRule.strategy 为 RuleConstant.RELATE 同时设置 FlowRule.ref_identity 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。

简单来说就是:当与A关联的资源B达到阀值后,就限流A自己。

如下,我们给资源B设置规则:QPS/1

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_spring cloud_06

我们给资源A修改规则:即只有当B触发限流时,A的QPS/1这个规则才生效

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_数据库_07

如下下图所示,如果B未触发限流,那么A的QPS/1是不生效的。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_限流_08

然后同时请求资源A、资源B,使B达到阈值,此时A也会返回错误信息。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_数据库_09

【3】链路

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_链路_10


简单来讲,资源的链路入口方将会受规则控制,其他的调用不关心。

添加pom文件

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-web-servlet</artifactId>
</dependency>

添加配置类:

@Configuration
public class FilterContextConfig {

    @Bean
    public FilterRegistrationBean sentinelFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CommonFilter());
        registration.addUrlPatterns("/*");
        // 入口资源关闭聚合
        registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
        registration.setName("sentinelFilter");
        registration.setOrder(1);
        return registration;
    }
}

定义一个service资源:

@Service
public class JaneService {
    // 定义限流资源
    @SentinelResource("common")
    public String common(){
        return "common";
    }
}

定义controller:

@Autowired
JaneService janeService;

@GetMapping("/testA")
public String testA(){
    janeService.common();
    return "testA";
}

@GetMapping("/testB")
public String testB(){
    janeService.common();
    return "testB";
}

给common添加链路规则:

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_sentinel_11


这样频繁请求testA将会报错,但是频繁请求testB正常,说明我们的链路控制生效。

SpringCloud Alibaba Sentinel 流量控制之流控模式实践总结_sentinel_12