草庐IT

Sentinel限流入门,与gatewway,nacos,boot搭配等

板栗炖牛肉 2023-03-28 原文

前言

  • 讲解spring boot中使用。spring cloud中使用(gateway、nacos中使用)。注意,只做限流讲解,同时spring boot为spring mvc框架。spring cloud使用spring webflux框架

  • 基础环境 spring boot 2.4.13sentinel 2021.1,nacos 2021.1gateway 3.0.7

  • 不提供sentinel控制台jar包,版本1.8.2。不提供nacos中心jar包,版本2.0.3

spring boot项目限流(需要gateway等的往下翻)

  • 在单独的spring boot整体项目中限流,此处我做的是代码持久化,注意是注解式

  • pom.xml文件配置

        <!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>

  • xxx.yml配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:30010  //控制包jar包地址。是否与控制台连接开关,不做测试建议注释,会产生本地文件
        heartbeat-interval-ms: 5000  //心跳时间ms
      enabled: true //Sentinel自动化配置是否生效
  • 创建自定义规则配置。注意,我这里spring boot项目是多模块,为了解耦才这么写
public abstract class CustomSentinelConfig {

    @PostConstruct
    private void config() {
        List<FlowRule> flowRules = new ArrayList<>();

        /**
         * 添加限流方式
         * 10次拒绝访问
         */
        FlowRule flowRule1 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule1.setResource("限流-10");
        //限流阈值
        flowRule1.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule1.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流,不支持线程
        flowRule1.setControlBehavior(0);
        //组装
        flowRules.add(flowRule1);

        /**
         * 添加限流方式
         * 5次等待排队
         */
        FlowRule flowRule2 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule2.setResource("限流等待-5");
        //限流阈值
        flowRule2.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule2.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流,不支持线程
        flowRule2.setControlBehavior(2);
        //超时时间设置
        flowRule2.setMaxQueueingTimeMs(60000);
        //组装
        flowRules.add(flowRule2);

        /**
         * 添加限流方式
         * 2次拒绝访问
         */
        FlowRule flowRule3 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule3.setResource("限流-2");
        //限流阈值
        flowRule3.setCount(2);
        //调用关系限流策略:直接、链路、关联
        flowRule3.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流,不支持线程
        flowRule3.setControlBehavior(0);
        //组装
        flowRules.add(flowRule3);

        /**
         * 添加限流方式
         * 10次等待排队
         */
        FlowRule flowRule4 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule4.setResource("限流等待-10");
        //限流阈值
        flowRule4.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule4.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule4.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流,不支持线程
        flowRule4.setControlBehavior(2);
        //超时时间设置
        flowRule4.setMaxQueueingTimeMs(60000);
        //组装
        flowRules.add(flowRule4);

        /**
         * 添加限流方式
         * 线程最多五个
         */
        FlowRule flowRule5 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule5.setResource("线程-5");
        //限流阈值
        flowRule5.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule5.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule5.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流,不支持线程
        flowRule5.setControlBehavior(0);
        //超时时间设置
        flowRule5.setMaxQueueingTimeMs(60000);
        //组装
        flowRules.add(flowRule5);


        /**
         * 组装限流
         */
        FlowRuleManager.loadRules(currentLimitRules(flowRules));
    }

    /**
     * 限流规则配置
     *
     * @param rules
     * @return
     */
    protected abstract List<FlowRule> currentLimitRules(List<FlowRule> rules);

}
/**
 * 自定义限流规则
 *
 * @date 2021-8-9
 */
@Configuration
public class SentinelConfig extends CustomSentinelConfig {

    @Override
    protected List<FlowRule> currentLimitRules(List<FlowRule> rules) {
        return rules;  //为了解耦,继承默认配置,此处自定义增添配置
    }
}
  • 在接口上使用,注意:限流可以在方法上使用,不仅仅只针对接口
    /**
     * 下载、文件
     *
     * @param url
     * @param response
     */
    @SentinelResource(value = "限流-10")  //value为对应规则
    @GetMapping("/download")
    public void download(@RequestParam String url, HttpServletResponse response) throws Exception {
        new RestBeanUtil<String, String>(null)
                .build(new OnCallBeanListener<String, String>() {
                    @Override
                    public String run(String value) throws Exception {
                        try {
                            log.info("文件下载:" + url);
                            ossService.handlerDownload(url, response);
                        } catch (Exception e) {
                            e.printStackTrace();
                            MinioUtil.downLoadFail(response, e);
                        }
                        return null;
                    }
                });
    }

  • 返回规则当限流时候,需要自定义一个规则配置
/**
 * 自定义、外接哨兵异常
 *
 * @date 2021/8/9
 */
@Configuration
public class CustomBlockHandler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = null;
        if (e instanceof FlowException) {
            //限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof DegradeException) {
            //BUSY_TOO_MANY_PEOPLE
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof ParamFlowException) {
            //热点参数限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof SystemBlockException) {
            //系统规则
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof AuthorityException) {
            //授权规则
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        }
        response.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        response.getWriter().write(msg);
        response.getWriter().close();
    }

}


  • RestBean是自定义的restful风格实体,RestCodeType为枚举类
    /**
     * 流量限制类
     */
    BUSY_BUSINESS(70000, "当前业务繁忙,请稍后再试"),

    BUSY_UNREACHABLE(70010, "当前业务暂停,请稍后再试"),

    BUSY_TOO_MANY_PEOPLE(70020, "当前访问人数过多,请稍后再试"),

    BUSY_IP_BAN(70030, "超出接口访问次数,请稍后再试"),

spring cloud 限流注意:框架为webflux

  • pom.xml文件配置
<!--gateway依赖,不能与web依赖放在一起-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.0.7</version>
        </dependency>

        <!--gateway与nacos获取微服务-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
            <version>3.0.5</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
            <scope>provided</scope>
        </dependency>

        <!-- 注册中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version>
        </dependency>

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>

        <!--sentinel-nacos-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.3</version>
        </dependency>

        <!--sentinel-gateway 暂时不用添加,后续讲解-->  
        <!--        <dependency>-->
        <!--            <groupId>com.alibaba.cloud</groupId>-->
        <!--            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>-->
        <!--            <version>2021.1</version>-->
        <!--        </dependency>-->

  • xxx.yml配置
---
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        group: remote
        namespace: b14470b8-2099-41c1-8652-8cad015b0b53


---
#限流配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:30010
        heartbeat-interval-ms: 5000
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            dataId: sentinel-service
            groupId: sentinel
            data-type: json
            rule_type: flow
            namespace: b14470b8-2099-41c1-8652-8cad015b0b53  //看是否为个人空间,否则去掉
      enabled: true //此处必须打开

---
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false
          lower-case-service-id: true
      routes:   //网关的路由,测试使用,不成功去掉
        - id: oss-service
          uri: lb://oss
          predicates:
            - Path=/oss/**
            - Method=GET,POST


  • 打开nacos中心,创建sentinel-service配置

    image.png

  • 文件配置

resource:资源名称
limitApp:来源应用
grade:阀值类型,0---线程数,1---QPS
count:单机阀值
strategy:流控模式,0---直接,1---关联,2---链路
controlBehavior:流控效果,0---快速失败,1---warmUp,2---排队等待
clusterMode:是否集群
[
    {
       "resource": "/authentication/queryUserList",
       "limitApp":"default",
       "grade":1,
       "count":1,
       "strategy":0,
       "controlBehavior":0,
       "clusterMode":false 
    },
    {
       "resource": "/main/s",
       "limitApp":"default",
       "grade":1,
       "count":1,
       "strategy":0,
       "controlBehavior":0,
       "clusterMode":false 
    }
]
  • 配置限流返回信息
@Configuration
public class SentinelHandler implements BlockRequestHandler {

    @Value("${customGateWay.sentinel.info:{\"result\":7000,\"message\":\"当前业务繁忙,请稍后再试\"}}")
    private String info;

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just(info), String.class);
    }
}

  • 启动项目


    image.png
image.png

spring 网关限流基于spring-cloud-alibaba-sentinel-gateway

  • 上面的spring cloud限流针对的是接口名称,加上下包后,将会是针对网关的限流
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
            <version>2021.1</version>
        </dependency>
  • 根据项目业务需求,看是针对单个接口限流还是某类业务限流。添加后,接口限流将会失败,二者应该是存一不兼容。

    image.png

  • 修改SentinelHandler的继承类,否则无法正常回调


//import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;



/**
 * 限流、处理器
 *
 * @date 2022/4/6
 */
@Configuration
public class SentinelHandler implements BlockRequestHandler {

    @Value("${customGateWay.sentinel.info:{\"result\":7000,\"message\":\"当前业务繁忙,请稍后再试\"}}")
    private String info;

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just(info), String.class);
    }
}

注意

  • 不必要的文件不使用sentinel控制台时,请注释dashboard监控,否则会产生大量警告日志
      transport:
#        dashboard: localhost:30010
        heartbeat-interval-ms: 5000

有关Sentinel限流入门,与gatewway,nacos,boot搭配等的更多相关文章

  1. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  2. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  3. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  4. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  5. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  6. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  7. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  8. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  9. ruby-on-rails - 无法创建新的 Rails 项目 : `require' : cannot load such file --/config/boot (LoadError) - 2

    我正在尝试创建一个新的Rails项目,Jakes-Air:codeJakeWengroff$railsnewMyNewProject-T但我一直收到这个错误:script/rails:5:in`require':cannotloadsuchfile--/Users/JakeWengroff/config/boot(LoadError)fromscript/rails:5:in`'检查Ruby版本,ruby-v,我明白了ruby2.1.2p95(2014-05-08revision45877)[x86_64-darwin13.0]当我想检查Rails的版本时,rails-v,我得到了与我

  10. Spring Boot集成ElasticSearach - 2

    文章目录前言一、Elasticsearch版本介绍二、客户端种类三、客户端与版本兼容性四、引入Elasticsearch依赖包五、客户端配置六、Elasticsearch使用前言ElasticSearch是Elastic公司出品的一款功能强大的搜索引擎,被广泛的应用于各大IT公司,它的代码位于https://github.com/elastic/elasticsearch,目前是一个开源项目。ElasticSearch公司的另外两个开源产品Logstash、Kibana与ElasticSearch构成了著名的ELK技术栈。。他们三个共同形成了一个强大的生态圈。简单地说,Logstash负责数据

随机推荐