实战:Springboot集成Sentinel实现流量控制、熔断降级、负载保护
作者:mmseoamin日期:2023-12-25

文章目录

    • 前言
    • 知识积累
      • 流量控制
      • 负载保护
      • 熔断降级
      • 官方文档
      • 实战演练
        • 部署sentinel-dashboard
          • 直接jar包部署
          • docker-compose编排
          • springboot集成sentinel
            • 基础架构搭建
            • sentinel控制台
            • sentinel验证
            • 延伸:系统自适应限流
              • 系统规则
              • 原理
              • 配置页面
              • 写在最后

                前言

                前面的文章我们学习了Hystrix并和springboot项目进行了集成,实现服务的熔断降级、隔离措施。但是Hystrix对流量的控制不是很好,仅仅信号量也只能对指定的接口进行限流,至于保护机制Hystrix也只是达到指标进行熔断。那么,有没有一种中间件可以在兼容熔断降级的同时精准实现流量控制和负载保护呢?回答是当然有的,就是我们今天的主角Spring Cloud Alibaba Sentinel。

                在这里插入图片描述

                知识积累

                Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定。

                流量控制

                Sentinel 可以针对不同的调用关系,按照指定的指标进行流程整形控制。而且整形的策略有直接拒绝、慢启动预热和匀速器三大模式,开发者可用根据自身需求选用策略实现流量的精准控制。

                负载保护

                Sentinel 可用提供精准的负载保护机制,如果被调用服务达到最大负载会将请求负载均衡到其他服务提供者上面,如果其他服务也达到了最大负载则会启动服务保护机制让请求流量和服务的负载达到平衡。

                熔断降级

                Sentinel 也是提供了基础的熔断降级功能,如果服务提供着抛出一次会直接降级走fallback逻辑,如果是配置指标则走blockhander逻辑。当然,如果服务集群达到最大负载会执行熔断功能,防止服务雪崩的发生。

                官方文档

                https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

                在这里插入图片描述

                实战演练

                部署sentinel-dashboard

                下载jar包

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

                在这里插入图片描述

                直接jar包部署

                nohup java -jar -Dserver.port=8109 sentinel-dashboard.jar &

                docker-compose编排

                有条件的可以直接使用dashboard镜像,如果pull缓慢则考虑自己构建镜像。

                dockerfile

                # this is sentinel-dashboard dockerfile
                # version 1.0
                # 基础镜像
                FROM openjdk:8-jre
                # 维护人
                MAINTAINER senfel<187@sina.cn>
                #jar
                COPY ./sentinel-dashboard.jar /home/app.jar
                # 端口
                EXPOSE 8109
                # 执行命令启动jar
                ENTRYPOINT ["java","-jar","/home/app.jar"]
                

                docker-compose.yml

                version: '3.3'
                services:
                  sentinel:
                    build: ./
                    image: senfel/sentinel-dashboard
                    container_name: sentinel-dashboard
                    ports:
                      - 8109:8109
                    environment:
                      JVM_OPTS: -server -Xmx512M -Xms512M -XX:MaxMetaspaceSize=256M -XX:CompressedClassSpaceSize=50M -XX:ReservedCodeCacheSize=240M -XX:MaxDirectMemorySize=400M
                    logging:
                      driver: "json-file"
                      options:
                        max-size: "10m"
                        max-file: "1"
                    volumes:
                      - "/home/test/demo/sentinel/logs:/root/logs"
                      - "/home/test/demo/sentinel/logs:/app-logs"
                    command: [
                      "--server.port=8109",
                      "--logging.file.path=/app-logs"
                    ]
                

                构件并启动容器

                docker-compose up -d --build
                

                查看sentinel容器

                docker ps | grep sentinel
                

                在这里插入图片描述

                springboot集成sentinel

                基础架构搭建

                持久化流量控制规则,其他规则只需要增加配置即可

                sentinel持久化到nacos 不持久每次重启都会清除规则

                增加maven依赖

                
                    com.alibaba.cloud
                    spring-cloud-starter-alibaba-sentinel
                    2.2.9.RELEASE
                
                
                    org.springframework.cloud
                    spring-cloud-starter-openfeign
                
                
                
                    com.alibaba.csp
                    sentinel-datasource-nacos
                    1.8.0
                
                

                增加bootstrap.yml配置 nacos自行搭建

                server:
                  port: 9999
                spring:
                  application:
                    name: test-demo
                  profiles:
                    active: uat
                  cloud:
                    nacos:
                      config:
                        server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
                        username: nacos
                        password: nacos
                        file-extension: yaml
                      discovery:
                        server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
                        username: nacos
                        password: nacos
                    sentinel:
                      transport:
                        dashboard: 10.10.22.174:8109
                        port: 8719
                      datasource:
                        ds1:
                          nacos:
                            server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
                            dataId: test-demo-sentinel.json
                            data-type: json
                            rule-type: flow
                            username: nacos
                            password: nacos
                            
                #开启sentinel
                feign:
                  sentinel:
                    enabled: true
                  circuitbreaker:
                    enabled: true            
                

                nacos新增限流配置

                流量控制

                resource:资源名称

                limitApp:来源应用

                grade:阈值类型,0代表线程数,1代表QPS

                count:单击阈值

                strategy:流控模式,0代表直接,1代表关联,2代表链路

                controlBehavior:流控效果,0代表快速失败,1代表Warm Up,2代表排队等待

                clusterMode:是否集群

                -其他规则大同小异这里不再累述

                -nacos配置与本文无关不再累述

                [
                  {
                    "resource": "testFeign",
                    "limitApp": "default",
                    "grade":   1,
                    "count":   1,
                    "strategy": 0,
                    "controlBehavior": 0,
                    "clusterMode": false
                  }
                ]
                

                启动类开启feign与nacos

                @SpringBootApplication
                @EnableDiscoveryClient
                @EnableFeignClients
                @Slf4j
                public class TestDemoApplication implements ApplicationRunner {
                    public static void main(String[] args) {
                        SpringApplication.run(TestDemoApplication.class, args);
                    }
                }
                

                测试用例

                /**
                 * testFeign
                 * fallback只负责业务异常
                 * blockHandler只负责sentinel配置超标
                 * 两个都配置,如果都出错,会进入blockHandler
                 * @param str
                 * @author senfel
                 * @date 2023/7/11 14:26
                 * @return java.lang.String
                 */
                @SentinelResource(value = "testFeign",blockHandler = "blockHandler",fallback = "handlerFallback")
                @GetMapping("/testFeign")
                public String testFeign(String str){
                    if(str.contains("y")){
                        throw new RuntimeException();
                    }
                    return testMQService.testFeign(str);
                }
                /**
                 * 异常阻塞处理
                 * @param str
                 * @author senfel
                 * @date 2023/7/11 14:44
                 * @return java.lang.String
                 */
                private String blockHandler(String str, BlockException blockException){
                    return "blockHandler"+"-"+str;
                }
                /**
                 * 降级处理
                 * @param str
                 * @author senfel
                 * @date 2023/7/11 14:44
                 * @return java.lang.String
                 */
                private String handlerFallback(String str,Throwable throwable){
                    return "handlerFallback"+"-"+str;
                }
                

                openfeign降级测试用例

                /**
                 * @author senfel
                 * @version 1.0
                 * @date 2023/7/03 15:04
                 */
                @Service
                @FeignClient(value = "test-demo",fallback = FallbackService.class)
                public interface TestService {
                    /**
                     * 测试sentinel
                     */
                    @GetMapping("/feign")
                    String feign(@RequestParam String str);
                }
                /**
                 * FallbackService
                 * @author senfel
                 * @version 1.0
                 * @date 2023/7/3 15:26
                 */
                @Service
                public class FallbackService implements TestService {
                    @Override
                    public String feign(String str) {
                        return ">>>>>客户端服务降级>>>>>";
                    }
                }
                
                sentinel控制台

                postman请求后查看 http://10.10.22.174:8109/

                在这里插入图片描述

                自动加载配置的流量规则

                在这里插入图片描述

                在这里插入图片描述

                sentinel验证

                验证主动控制流量

                127.0.0.1:9999/testFeign?str=fffffffffss

                在这里插入图片描述

                验证异常控制流量

                127.0.0.1:9999/testFeign?str=fffffffffyy

                在这里插入图片描述

                验证客户端feign降级

                127.0.0.1:9999/testFeign?str=fffffffffss

                在这里插入图片描述

                查看实时监控

                在这里插入图片描述

                延伸:系统自适应限流

                系统规则

                系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

                系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

                系统规则支持以下的模式:

                Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。

                CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。

                平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。

                并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。

                入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

                原理

                我们把系统处理请求的过程想象为一个水管,到来的请求是往这个水管灌水,当系统处理顺畅的时候,请求不需要排队,直接从水管中穿过,这个请求的RT是最短的;反之,当请求堆积的时候,那么处理请求的时间则会变为:排队时间 + 最短处理时间。

                在这里插入图片描述

                配置页面

                在这里插入图片描述

                写在最后

                Sentinel实现流量控制、熔断降级、负载保护的实际使用个人觉得还是比较简单,只需要根据官方文章集成和配置使用即可。sentinel的流量控制和负载保护以及高性能都优于hystrix,并提供可视化控制台。如果在可用性和可靠性较高和重要的服务集群场景中,可以优先考虑sentinel。

                ⭐️路漫漫其修远兮,吾将上下而求索 🔍