Sentinel组件限流降级

news2024/11/16 1:46:42

官网:

home | Sentinel

文档不是很全, 关于nacos的配置中心的使用完全没有

常见的限流算法

  • 静态窗口限流: 即规定1秒内只能固定处理多少请求
  • 动态窗口限流: 同样是规定1秒内处理多少请求, 但是统计方式与第一个不同, 比如2.5秒则是统计1.5秒到现在的请求数
  • 漏桶限流: 进来可以大流量接收, 处理则是匀速处理
  • 令牌桶算法: 漏桶放的是请求, 令牌桶则是放的令牌, 匀速生成令牌, 只有获取令牌的请求才能处理
  • 令牌大闸: 比如车票, 最开始的数量是固定的, 一旦产生了足够的令牌就不再产生了

使用方法

如果是单机的SpringBoot可以使用sentinel官方的文档:

quick-start | Sentinel

如果是SpringCloud可以参考SpringCloudAlibaba的官方文档:

Sentinel · alibaba/spring-cloud-alibaba Wiki · GitHub

代码实现

添加pom依赖:

<!-- 限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

限流方法处理:

注意降级的方法的入参和返回结果都需要保持一致

/**
     * 降级方法,需包含限流方法的所有参数和BlockException参数
     * @param req
     * @param e
     */
    public void doConfirmBlock(ConfirmOrderDoReq req, BlockException e) {
        LOG.info("购票请求被限流:{}", req);
        throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_FLOW_EXCEPTION);
    }

    @SentinelResource(value = "doConfirm", blockHandler = "doConfirmBlock")
    public void doConfirm(ConfirmOrderDoReq req) {
        //do business....
    }

在main函数添加规则:

@SpringBootApplication
@ComponentScan("com.louye")
@MapperScan("com.louye.train.*.mapper")
@EnableFeignClients("com.louye.train.business.feign")
@EnableCaching
public class BusinessApplication {
    private static final Logger LOG = LoggerFactory.getLogger(BusinessApplication.class);

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(BusinessApplication.class);
        Environment env = app.run(args).getEnvironment();
        LOG.info("启动成功!!");
        LOG.info("地址: \thttp://127.0.0.1:{}{}/hello", env.getProperty("server.port"), env.getProperty("server.servlet.context-path"));

        // 限流规则(这里才是主要, 如果后续引入了sentinel控制台, 则可以直接在控制台进行规则的控制, 不需要代码形式定义限流规则)
        initFlowRules();
        LOG.info("已定义限流规则");
    }

    /**
     * 定义限流规则
     */
    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("doConfirm");// 资源名需要跟自己添加注解的地方的方法名一致
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

}

搭建控台监控流量

参考: dashboard | Sentinel

使用官方jar包

下载指定版本后, 启动:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

根据官方文档: 初始用户名: sentinel, 密码: sentinel

访问启动的端口即可: http://localhost:8080/

代码中需要增加的配置:

# sentinel
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=localhost:8080

控制台进行限流规则的控制:

但是控制台这样定义的规则是保存在应用内存内部的, 应用一旦重启就没有了, 需要考虑规则的持久化

使用Docker构建镜像

官方目前还没有提供Docker镜像,可以根据需要自己构建镜像

参考博客:

【Mac M1+】Docker 安装 Sentinel - 掘金

下载jar包:https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar

创建sentinel-dashboard-1.8.6目录, 将jar包下载到当前文件夹下,并且编写Dockerfile文件:

FROM openjdk:8

MAINTAINER louye clf1256233771@gmail.com

WORKDIR /cloud-sentinel

# 下载的 jar 包和 Dockerfile 在同一目录下
ARG JAR_FILE=./sentinel-dashboard-1.8.6.jar

COPY ${JAR_FILE} cloud-sentinel.jar

EXPOSE 8080

ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Dserver.port=8080 -Djava.security.egd=file:/dev/./urandom"

CMD java $JAVA_OPTS -jar cloud-sentinel.jar

构建镜像:

docker build -t sentinel:1.8.6 .

启动镜像:

 docker run --name sentinel_1.8.6 --platform linux/arm64 -p 8080:8080 -d sentinel:1.8.6

使用nacos持久化sentinel的规则配置

添加依赖

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

添加配置到bootstrap.properties:

# sentinel + nacos
spring.cloud.sentinel.datasource.flow.nacos.serverAddr=127.0.0.1:8848
spring.cloud.sentinel.datasource.flow.nacos.namespace=train
spring.cloud.sentinel.datasource.flow.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.flow.nacos.dataId=sentinel-business-flow
spring.cloud.sentinel.datasource.flow.nacos.ruleType=flow

在nacos中配置sentinel的规则sentinel-business-flow, 类型选择json:

[
  {
    "resource": "doConfirm",
    "limitApp": "default",
    "grade": 1,
    "count": 100,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "confirmOrderDo",
    "limitApp": "default",
    "grade": 1,
    "count": 4,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "hello",
    "limitApp": "default",
    "grade": 1,
    "count": 10,
    "strategy": 0,
    "controlBehavior": 1,
    "warmUpPeriodSec": 2,
    "clusterMode": false
  }
]
  • resource: 资源名, 添加注解@SentinelResource时定义的
  • limitApp: 针对来源
  • grade: 0: 并发线程数, 1: QPS
  • count: 单机阈值
  • strategy: 流控模式, 0: 直接, 1: 关联, 2: 链路
  • controlBehavior: 流控效果, 0: 快速失败, 1: warm up(预热用于加载数据), 2: 排队等待
  • clusterMode: 是否集群

配置后查看sentinel控制台就可以看到对应的限流规则:

不同限流的概念

  • 关联限流: strategy=1, 在下单和支付的场景中, 这两个操作是不同的两个接口, 可能存在某些原因支付处理速度慢需要限流, 所以关联着下单的接口也会自动受到限流
  • 链路限流: strategy=2, 在两个接口调用同一个Service的方法时, 我们只想对某一个方法的某个接口进行限流,但是并不影响另一个, 采用链路就可以只对某个链路的请求进行限制

熔断配置

场景, 服务A调用服务B, 这时候可能服务B处理很慢或者B服务出现异常, 熔断则直接不对服务B进行访问了然后继续往后走. 但是原有的调用逻辑怎么处理就需要我们补充备用方案.

引入基本依赖:

<!-- 限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

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

bootstrap.properties添加配置:

# sentinel
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=localhost:8080
# sentinel + nacos, degrade这个名字可以自定义
spring.cloud.sentinel.datasource.degrade.nacos.serverAddr=127.0.0.1:8848
spring.cloud.sentinel.datasource.degrade.nacos.namespace=train
spring.cloud.sentinel.datasource.degrade.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.degrade.nacos.dataId=sentinel-batch-degrade
spring.cloud.sentinel.datasource.degrade.nacos.ruleType=degrade

# sentinel 默认不监控feign, 需要配置才能监控feign
feign.sentinel.enabled=true
# 上面改成true后, 启动会报注入失败, 需要改成懒加载
spring.cloud.openfeign.lazy-attributes-resolution=true

nacos中配置降级规则:

[{
  "resource": "GET:http://business/business/hello",
  "grade": 0,
  "count": 201,
  "timeWindow": 11,
  "minRequestAmount": 6,
  "statIntervalMs": 1000,
  "slowRatioThreshold": 0.3
}]

对应的展示:

  • resource: 资源名
  • grade: 熔断策略
  • count: 最大RT(响应时间), 超过这个时长则是慢调用
  • timeWindow: 熔断时长
  • minRequestAmount: 最小请求数
  • statIntervalMs: 统计时长
  • slowRatioThreshold: 比例阈值

降级处理配置:

编写fallback的方法实现:

@Component
public class BusinessFeignFallback implements BusinessFeign {
    @Override
    public String hello() {
        return "Fallback";
    }
}

配置Feign, 添加熔断后的处理器:

@FeignClient(value = "business", fallback = BusinessFeignFallback.class)
public interface BusinessFeign {
    @GetMapping("/business/hello")
    String hello();
}

热点参数限流

Sentinel 热点参数限流原理 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/731957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【全栈第三课】通过ChatGPT快速入门NodeJS

前言 往期全栈课程&#xff1a; Vue从入门到精通 微信小程序从入门到精通 Node.js基础 简介 Node.js是什么&#xff1f; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O的模型&#xff0c;使其轻量又高效。Node.js …

迎接高考的倒计时网页(❤️好看好用❤️)HTML+CSS+JS

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

并发编程_jmm部分

1. JMM 理解 前提&#xff1a;并发编程有3大问题&#xff0c;可见性、有序性、原子性。 导致可见性的原因是缓存&#xff0c;有序性的原因是 编译器优化。解决方法就是直接禁用缓存和编译器优化&#xff0c;导致程序性能堪忧。 因此合理的方案就是按需禁用缓存和编译器优化。 …

MySQL数据库——单表查询练习

一、练习素材 创建表 CREATE TABLE emp (empno int(4) NOT NULL,ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,mgr int(4) NULL DEFAULT NULL,hireda…

遗传算法核心理解,python代码

遗传算法的核心&#xff0c;就在于&#xff0c;把待求的变量转化成二进制串&#xff0c;二进制串就像dna&#xff0c;可以对它的其中某几位进行交换&#xff0c;变异等操作&#xff0c;然后再转换回十进制&#xff0c;带入目标函数&#xff0c;计算适应度&#xff0c;保留适应度…

【lambda函数】lambda()函数

lambda&#xff08;&#xff09; lambda&#xff08;&#xff09;语法捕捉列表mutable lambda 底层原理函数对象与lambda表达式 lambda&#xff08;&#xff09;语法 lambda表达式书写格式&#xff1a; [capture-list] (parameters) mutable -> return-type{ statement }咱…

【数据结构】排序:插入排序与希尔排序详解

本章开始就要分享一些常用的排序方法&#xff0c;我们的日常生活中很多地方都要使用排序&#xff0c;比如电商平台可以按照你的需求进行排序&#xff0c;或者是你想了解大学的综合排名时 我们之前也学到过一些简单的排序比如冒泡排序&#xff0c;虽然他在时间复杂度上可以说是依…

归并排序(思路+代码)

变量&#xff1a; left、right、privot、temp[]、leftIndex、k 思路&#xff1a; 代码&#xff1a; import java.util.Arrays;public class Queue8 {public static void main(String[] args) {int[] arr {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};sort(arr,0,arr.length-1);System.ou…

AST-抽象语法树

js加密解混淆首先想到的是AST语法树&#xff0c;那么什么是AST呢&#xff0c;学习AST过程的一些笔记 1.AST是JS执行的第一步是读取 js 文件中的字符流&#xff0c;然后通过词法分析生成令牌流Tokens&#xff0c;之后再通过语法分析生成 AST&#xff08;Abstract Syntax Tree&a…

3D 旋转木马

在工作中我们常用到3D装换和3D位移 主要知识点 3D位移&#xff1a;transale3d(x,y,z)3D旋转&#xff1a;rotate3d(x,y,z)透视&#xff1a;perspective3D呈现 transfrom-style 1、 transale3d translform: translform:translateX(100px):仅仅是在x轴上移动translform:transl…

[NOI2014] 随机数生成器(模拟+贪心)

题面 [NOI2014] 随机数生成器 - 洛谷 题解 缝合题 第一部分&#xff0c;直接模拟题目操作生成二维数组即可&#xff0c;复杂度O(n*mQ) 第二部分&#xff0c;是一个比较经典的字典序贪心 首先肯定需要将最小的数放到路径上&#xff0c;这样可选的剩下的数就被限制在了最小数…

Redis 管道

问题由来&#xff1a;如何优化频繁命令往返造成的性能瓶颈&#xff1f; Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。 一个请求会遵循以下步骤&#xff1a; 1、客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听S…

Codeforces Round 883 (Div. 3) A~G

比赛链接&#xff1a;Dashboard - Codeforces Round 883 (Div. 3) - Codeforces 目录 A. Rudolph and Cut the Rope B. Rudolph and Tic-Tac-Toe C. Rudolf and the Another Competition D. Rudolph and Christmas Tree E. Rudolf and Snowflakes F. Rudolph and Mimic…

JavaWeb项目(包含SSM项目)部署到Linux云服务器

目录 一、云服务器环境部署 1、安装JDK 查看JDK的命令为&#xff1a; 安装JDK命令&#xff1a; 2、安装Tomcat 2.1 安装步骤 2.2 验证Tomcat是否启动成功 3、安装MySQL 二、部署 Web 项目到 Linux 2.1 在云服务器中数据库建库建表 2.2 修改部署项目连接数据库密码 …

Qt(Day2)

实现登录框中&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;并跳转到其他界面&#xff1a;

Go实现在线词典翻译(三种翻译接口,结合sync)

火山翻译 首先介绍用火山翻译英译汉。 package mainimport ("bufio""bytes""encoding/json""fmt""io""log""net/http""os""strings""unicode" )type DictRequestHS st…

第四章:角色和菜单管理功能【基于Servlet+JSP的图书管理系统】

角色和菜单功能 一、角色功能 接下来我们可以完成角色管理的增删改查操作 1. Bean对象 创建sys_role对应的实体对象SysRole Data public class SysRole {private Integer id;private String name;private String notes;private Date createTime; }2. Dao层 现在我们就可以在D…

JVM(Java虚拟机)详解

目录 一、JVM内存区域划分 1. 什么是内存区域划分以及为啥要进行区域划分 2. JVM内存区域划分详解 3. 堆区详解&#xff1a; 4. 给一段代码&#xff0c;问某个变量是在那个区域上&#xff1f; 二、JVM类加载机制 1.类加载的过程 2. 类加载的时机 3. 双亲委派模型&#xff08…

下班前几分钟,我彻底玩懂了tmux

目录 1. tmux简介2. Session3. Window4. Pane5. 自定义tmux配置6. 在shell脚本中操纵tmuxReferences 1. tmux简介 tmux&#xff08;terminal multiplexer&#xff09;是一个非常强大的工具&#xff0c;主要有以下几点功能&#xff1a; 终端复用&#xff1a; tmux 使你能够在一…

Linux分布式应用 Zabbix监控配置[添加主机 自定义监控内容 邮件报警 自动发现/注册 代理服务器 高可用集群]

-------------------- 添加 zabbix 客户端主机 -------------------- 关闭防火墙 systemctl disable --now firewalld setenforce 0 hostnamectl set-hostname zbx-agent01 服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 服务端和客户端都设…