美文网首页
02-sentinel限流与熔断

02-sentinel限流与熔断

作者: wshsdm | 来源:发表于2022-12-19 16:44 被阅读0次

    1 sentinel应用场景之雪崩问题

    • 雪崩问题

    微服务调用链路中的某个服务故障,引起整个链路中所有微服务都不可用,这就是雪崩。

    • 解决雪崩问题常见四种方式
    1. 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误;
    2. 舱壁模式:限定每个业务使用的线程数量;
    3. 熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求;
    4. 流量控制:限制业务访问的QPS,避免服务因流量的突增而产生故障;

    2 限流技术

    2.1 常见的限流技术对比

    对比项 Sentinel Hystrix
    隔离策略 信号量隔离(并发线程数限流)(模拟信号量) 线程池隔离/信号量隔离
    熔断降级策略 基于响应时间、异常比率、异常数 基于异常比率 快速失败的本质功能
    实时统计实现 滑动窗口(LeapArray) 滑动窗口(基于 RxJava)
    扩展性 多个扩展点 插件的形式
    限流 基于QPS,支持基于调用关系的限流 有限的支持(并发线程数或信号量大小)
    流量整形 支持预热模式、匀速器模式、预热排队模式 不支持(排队)
    系统自适应保护 支持(仅对linux生效) 不支持
    配置持久化 ZooKeeper, Apollo, Nacos Git/svn/本地文件
    黑白名单 支持 不支持

    2.2 限流算法

    1. 计数器算法
      在指定周期内累加访问次数,当访问次数达到设定的阈值时,触发限流策略,当进入下一个时间周期时进行访问次数清零;
    2. 滑动窗口算法
      为了解决计数器算法带来的临界问题,滑动窗口算法是在固定窗口中分割出多个小时间窗口,分别在每个小时间窗口中记录访问次数,然后根据时间将窗口往前滑动并删除过期的小时间窗口,最终只需要统计滑动窗口范围内的所有小时间窗口总数;sentinel就采用滑动窗口算法来实现限流;
    3. 令牌桶限流算法
      系统以一个恒定速度向固定容量的令牌桶中放入令牌,如果有我客户端请求过来,则需要先从令牌桶中拿到令牌以获得访问资格;
    4. 漏桶限流算法
      该算法主要作用是控制数据注入网络的速度,平滑网络上的突发流量;
      在漏桶算法内部维护一个容器,这个容器以恒定速度出水,不管上面水流速度多快,漏桶水滴的流出速度始终保持不变。(中间件就使用了漏桶限流的思想,不管生产者的请求量多大,消息的处理能力取决于消费者)

    3 服务熔断于降级

    3.1 基本概念

    在高并发场景中,由于微服务架构中服务拆分粒度较细,请求链路较长,如某个服务因为网络延迟或请求超时等原因不可用时,会导致当前请求阻塞,很可能出现请求堆积从而导致出现雪崩效应;
    服务熔断:是指当某个服务提供者无法正常为服务调用者提供服务时,如请求超时、服务异常等,为了防止整个系统出现雪崩效应,暂时将出现故障的接口隔离出来,断绝与外部接口的联系,当触发熔断之后,后续一段时间内该服务调用者的请求都会直接失败,直到目标服务恢复正常;
    服务降级需要有一个参考指标,一般有几种常见方案:

    1. 平均响应时间
    2. 异常比例
    3. 异常数量

    4 Sentinel基本使用

    4.1 基本概念

    sentinel是分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、服务降级、系统负载保护等多个维度来保障微服务的稳定性;
    sentinel组成:
    核心库、控制台

    3.1 控制启动sentinel控制台

    配置项 默认值 说明
    server.port 8080 默认端口
    sentinel.dashboard.auth.username sentinel 用户名
    sentinel.dashboard.auth.password sentinel 密码
    • 启动控制台
    java -Dserver.port=8000 -Dcsp.entinel.dashboard.server=localhost:8000 -Dproject.name=sentinel-dashboard  -jar sentinel-dashboard-1.8.6.jar 
    

    3.3 微服务中整合sentinel

    • 基本步骤
    1. 定义资源
    2. 定义限流规则
    3. 检验规则是否生效
    • 创建父容器pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.pingsp</groupId>
        <artifactId>pingsp-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>pingsp-security</module>
        </modules>
        <packaging>pom</packaging>
        <!--统一版本-->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <!-- spring boot -->
            <spring-boot.version>2.4.2</spring-boot.version>
            <!-- spring cloud -->
            <spring-cloud.version>2020.0.1</spring-cloud.version>
            <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
            <!-- db && orm -->
            <mysql.version>8.0.19</mysql.version>
            <druid.version>1.2.4</druid.version>
            <mybatis-plus.version>3.4.3</mybatis-plus.version>
            <!-- tools -->
            <lombok.version>1.18.24</lombok.version>
            <hutool.version>5.8.5</hutool.version>
            <!--自定义依赖库版本-->
            <project.version>1.0-SNAPSHOT</project.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
        </dependencies>
        <dependencyManagement>
            <dependencies>
                <!--Spring Cloud 相关依赖-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--Spring Cloud & Alibaba 相关依赖-->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>${spring-cloud-alibaba.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!-- SpringBoot 依赖配置 -->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--持久层依赖配置-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid-spring-boot-starter</artifactId>
                    <version>${druid.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <version>${mybatis-plus.version}</version>
                </dependency>
                <!--流量控制-->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
                    <version>${spring-cloud-alibaba.version}</version>
                </dependency>
                <!--自定义通用模块-->
            </dependencies>
        </dependencyManagement>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    </project>
    
    • 创建自定义模块,加入sentinel依赖
    <dependencies>
            <!-- 配置读取 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </dependency>
            <!-- Spring Cloud & Alibaba -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-bootstrap</artifactId>
            </dependency>
            <!-- 注册中心 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            </dependency>
            <!-- 配置中心 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
        </dependencies>
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    • 添加sentinel服务配置 application.yml
    server:
      port: 8001
    spring:
      application:
        # 应用程序名称
        name: pingsp-security
      cloud:
        nacos:
          discovery:
            # 服务发现
            server-addr: localhost:8848
          config:
            # 配置服务器
            server-addr: localhost:8848
            shared-configs:
              - dataId: ds.yaml
                refresh: true
        sentinel:
          transport:
            port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
            dashboard: localhost:8000 #指定控制台服务的地址
    
    • 重新加载sentinel控制台页面

    Sentinel的控制台其实就是一个SpringBoot编写的程序。我们需要将我们的微服务程序注册到控制台上,
    即在微服务中指定控制台的地址, 并且还要开启一个跟控制台传递数据的端口, 控制台也可以通过此端口
    调用微服务中的监控程序获取微服务的各种信息

    3.4 实现接口限流

    image.png

    4 sentinel功能

    4.1 基本概念

    • 资源
      资源就是sentinel要保护的东西(可以是一个服务、一个方法或一段代码)
    • 规则
      规则就是用来定义如何进行保护资源(流量控制规则、熔断降级规则以及系统保护规则)

    4.2 容错的三个方面

    1. 流量控制
    2. 熔断降级(通过限制并发线程数和通过响应时间对资源进行降级)
    3. 系统负载保护

    5 sentinel规则

    5.1 流控规则

    流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时对流
    量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性;


    image.png

    资源名:唯一名称,默认是请求路径,可自定义
    针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
    阈值类型单机阈值:QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流
    线程数:当调用该接口的线程数达到阈值的时候,进行限流
    是否集群:暂不需要集群

    • sentinel共有三种流控模式,分别是:
      直接(默认):接口达到限流条件时,开启限流
      关联:当关联的资源达到限流条件时,开启限流 [适合做应用让步]
      链路:当从某个接口过来的资源达到限流条件时,开启限流

    相关文章

      网友评论

          本文标题:02-sentinel限流与熔断

          本文链接:https://www.haomeiwen.com/subject/zvjufdtx.html