【Spring Cloud Alibaba 微服务教程】 Sentinel 流量控制

2020/05/05

Sentinel 流量控制

快速上手

1、创建应用

创建一个命名为: sentinel-cloud-view-example 的 Spring cloud 应用,

2、添加依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mtcarpenter</groupId>
    <artifactId>sentinel-cloud-view-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sentinel-cloud</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <alibaba.version>2.1.2.RELEASE</alibaba.version>
        <spring.cloud.version>Greenwich.RELEASE</spring.cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

3、增加配置

application.properties 中配置 sentinel dashboard 的地址:

# 服务名称
spring.application.name=sentinel-view-example 
# 服务端口
server.port=8081
# sentinel dashboard
spring.cloud.sentinel.transport.dashboard=localhost:8080
  • port:项目端口
  • spring.application.name:服务名称
  • spring.cloud.sentinel.transport.dashboard: sentinel dashboard 界面地址

4、加注解

在启动类上加入注解,这里暂无注解。

5、控制类

@RestController
@RequestMapping("/flow")
public class FlowController {

    @GetMapping("/test")
    public String test(){
        return "mtcarpenter:test";
    }

}

6 、启动程序

多访问几次接口 http://localhost:8081/test/echo

7、sentinel 界面查看状态

因为 sentinel 默认是懒加载的,所以通过接口访问出发控制面板的显示。

  • 每一个请求的接口被都会展示,很方便看到如,请求的时间通过的 QPS拒绝的 QPS响应时间(ms)

流控规则配置

新手上路

  • 进入簇点链路,找到上面我们请求的flow/test出现在界面中,现在配置该接口的 流控

e6efa83d

  • 配置单机阀值

一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果:

  • resource:资源名,即限流规则的作用对象
  • count: 限流阈值
  • grade: 限流阈值类型(QPS 或并发线程数)
  • limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
  • strategy: 调用关系限流策略
  • controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)

配置之后成功会自动跳转到流控规则,也可以通过流控规则直接配置。

  • 流控规则

  • 验证流控规则配置是否成功

    • 未被限流正常返回

    • 限流返回如下

在这里实现了使用sentinel接口限流。

初试牛刀

关联资源

FlowController新增如下接口用于关联资源测试

@GetMapping("/test-a")
public String testa(){
    return "mtcarpenter:test-a";
}

FlowController新增test-a接口用于测试流控规则中关联资源。

这里表达的意思是关联资源超过1,资源名将被限流。

接口flow/test-a超过 1 , flow/test 将被限流。

  • postman Runner 请求 flow/test-a

02fbe8fa-6ac3-1731-e345-378171ee01f2.png

  • flow/test-a一直被请求的时候,flow/test请求会被限流

链路

  • 新建 FlowService,作为公共访问方法。
@Service
public class FlowService {

    @SentinelResource("common")
    public String common(){
        return "common";
    }
}

@SentinelResource("common") 定义资源为common

  • FlowController新增如下接口用于关联资源测试

    @Autowired
    private FlowService flowService;

	@GetMapping("/test-b")
    public String testb(){
        flowService.common();
        return "mtcarpenter:test-b";
    }

    @GetMapping("/test-c")
    public String testc(){
        flowService.common();
        return "mtcarpenter:test-c";
    }

sentinel1.7.0 链路需要配置开启链路限流如下,(如不需要链路限流,application,配置类,依赖可以不加入):

application.properties
spring.cloud.sentinel.filter.enabled=false
配置类
@Configuration
public class FilterContextConfig {
    /**
     * @NOTE 在spring-cloud-alibaba v2.1.1.RELEASE及前,sentinel1.7.0及后,关闭URL PATH聚合需要通过该方式,spring-cloud-alibaba v2.1.1.RELEASE后,可以通过配置关闭:spring.cloud.sentinel.web-context-unify=false
     * 手动注入Sentinel的过滤器,关闭Sentinel注入CommonFilter实例,修改配置文件中的 spring.cloud.sentinel.filter.enabled=false
     * 入口资源聚合问题:https://github.com/alibaba/Sentinel/issues/1024 或 https://github.com/alibaba/Sentinel/issues/1213
     * 入口资源聚合问题解决:https://github.com/alibaba/Sentinel/pull/1111
     */
    @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;
    }
}

new CommonFilter()引入所需包无法找到,引入以下依赖

加入依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-web-servlet</artifactId>
    <version>1.7.0</version>
</dependency>

链路这里踩坑,之前在使用Sentinel 1.6.2 默认是开启得,不断迭代的版本有所变化,可以通过Issues进行查看。

  • test-btest-c都调用 common 方法,重新启动程序分别请求这两个接口,在 sentinel dashboard出现得资源common

  • 配置资源名common流控规则如下

使用 common中得入口资源/flow/test-c,单机阈值为1限流,其他使用common资源正常使用。

  • /flow/test-c被限流如下:

流控效果

当 QPS 超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:直接拒绝Warm Up匀速排队

直接拒绝

达到阈值直接抛出异常,默认Wie快速失败。

Warm Up 冷启动,预热

官方文章参看:限流—冷启动

常用在秒杀时,用图举例,现在单机阀值为100, 设置预热之后,现在的阀值实际为 100/3(可参看上面的冷启动链接) ,即阀值为33,然后过了10秒,阀值才会达到 100。

排队等待

官方文章参看:流量控制-匀速排队模式

如上图举例,单机阈值超过10,将进入排队等待,最长等待超时时间为10000毫秒

Sentinel 踩的坑

  • spring.application.name 多了一个空格引起的一场翻车事故。

  • 有无空格启动各启动一次,进入 sentinel 控制台如下:

63cddcb2-c680-1a0d-32c9-7cb4a9adff7d

  • 空格出现导致的问题

降级无法使用。

总结

**由于版本不断变化,当前在 cloud alibaba 2.1.2.RELEASE 环境测试 **

sentinel 的配置比较丰富,更多相关流量控制可以参看如下:

文章参考

  • https://github.com/alibaba/Sentinel

代码示例

本文示例代码访问下面查看仓库:

其中,本文示例代码名称:

  • sentinel-cloud-view-example:流量控制


微信扫描二维码,关注一个有故事的程序员

(转载本站文章请注明作者和出处 山间木匠-mtcarpenter

Post Directory

扫码关注公众号:山间木匠
发送 290992
即可立即永久解锁本站全部文章