【SpringCloudAlibaba】Sentinel使用

news2024/11/24 18:28:59

文章目录

  • 概述
    • 官网
    • 解决的问题
    • 主要特性
  • 配置
    • 下载可视化控制台
    • POM
    • YML
  • 流控规则
      • 直接(默认)
      • 关联
      • 链路
  • 降级规则
    • 降级策略实战
      • RT
      • 异常比例
      • 异常数
  • 热点key限流
    • 示例:
    • 高级选项:参数例外项
    • 其他
  • 系统规则
  • @SentinelResource
    • 按资源名称限流+后续处理
    • 按照Url地址限流+后续处理
    • 面临的问题
    • 客户自定义限流处理逻辑
  • 服务熔断功能
    • OpenFeign
  • 多种熔断框架比较
  • 规则持久化
    • 配置
      • POM
      • YML
      • 添加Nacos业务规则配置
  • 其他示例
    • 自适应限流的示例

概述

官网

https://github.com/alibaba/Sentinel
中文:
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
https://sentinelguard.io/zh-cn/docs/introduction.html

解决的问题

  1. 服务雪崩
  2. 服务降级
  3. 服务熔断
  4. 服务限流

主要特性

在这里插入图片描述

配置

下载可视化控制台

https://github.com/alibaba/Sentinel/releases
在这里插入图片描述

POM

<!--SpringCloud ailibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

YML

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        #Nacos服务注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719

management:
  endpoints:
    web:
      exposure:
        include: '*'

Sentinel采用的懒加载

流控规则

在这里插入图片描述

直接(默认)

  1. 资源名:默认rest路径名
  2. 来源:默认

在这里插入图片描述

关联

当与A关联的资源B达到阀值后,就限流A自己(B导致A挂)
B惹事,A挂了
1.预热

  • 公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
  • 默认coldFactor为3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。
  • 刚开始不行,后续慢慢OK

应用场景:
如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。
2.匀速排队

匀速排队,阈值必须设置为QPS

https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
在这里插入图片描述
设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

链路

降级规则

https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

  • Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,
    让请求快速失败,避免影响到其它的资源而导致级联错误。

  • 当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

在这里插入图片描述

半开的状态系统自动去检测是否请求有异常,
没有异常就关闭断路器恢复使用,
有异常则继续打开断路器不可用。具体可以参考Hystrix

Sentinel的断路器是没有半开状态的

降级策略实战

RT

在这里插入图片描述
在这里插入图片描述

异常比例

在这里插入图片描述
在这里插入图片描述
按照上述配置,
单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次;

开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。
断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了。

异常数

时间窗口一定要大于等于60秒。

在这里插入图片描述
在这里插入图片描述

热点key限流

官网:
https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
何为热点
热点即经常访问的数据,很多时候我们希望统计或者限制某个热点数据中访问频次最高的TopN数据,并对其访问进行限流或者其它操作

兜底方法:
分为系统默认和客户自定义,两种
从HystrixCommand 到@SentinelResource

限流模式只支持QPS模式,固定写死了。(这才叫热点)

  • @SentinelResource注解的方法参数索引,0代表第一个参数,1代表第二个参数,以此类推
  • 单机阀值以及统计窗口时长表示在此窗口时间超过阀值就限流。
  • 上面的抓图就是第一个参数有值的话,1秒的QPS为1,超过就限流,限流后调用dealHandler_testHotKey支持方法。

示例:

class TestController{
	// 此处value的值是资源名可以为abc都行与之后dashboard中配置的资源名对应就可以
	@GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2)
    {
        //int age = 10/0;
        return "------testHotKey";
    }
    public String deal_testHotKey (String p1, String p2, BlockException exception)
    {
        return "------deal_testHotKey,o(╥﹏╥)o";  //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
    }
}

在这里插入图片描述

高级选项:参数例外项

前提条件
注意:热点参数的注意点,参数必须是基本类型或者String

当p1等于5的时候,阈值变为200
在这里插入图片描述

其他

@SentinelResource
处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;

RuntimeException
int age = 10/0,这个是java运行时报出的运行时异常RunTimeException,@SentinelResource不管

总结
@SentinelResource主管配置出错,运行出错该走异常走异常

// 有fallback解决后面会细看
 @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey" fallBack="")

系统规则

官网:
https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81
仅对入口流量生效

  • 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 达到阈值即触发系统保护。
    在这里插入图片描述

@SentinelResource

按资源名称限流+后续处理

在这里插入图片描述

按照Url地址限流+后续处理

在这里插入图片描述

面临的问题

  1. 系统默认的,没有体现我们自己的业务要求。
  2. 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
  3. 每个业务方法都添加一个兜底的,那代码膨胀加剧。
  4. 全局统一的处理方法没有体现。

客户自定义限流处理逻辑

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
        blockHandlerClass = CustomerBlockHandler.class,//异常处理类
        blockHandler = "handlerException2")//异常处理方法
public CommonResult customerBlockHandler()
{
    return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003"));
}
public class CustomerBlockHandler
{
    public static CommonResult handlerException(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定义,global handlerException----1");
    }
    public static CommonResult handlerException2(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定义,global handlerException----2");
    }
}

在这里插入图片描述

服务熔断功能

sentinel整合ribbon+openFeign+fallback

fallback管运行异常(管java)
blockHandler管控制台配置违规(管dashboard中配置)

@SentinelResource(value = "fallback",
fallback = "handlerFallback",
blockHandler = "blockHandler")

若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。
exceptionsToIgnore

//exceptionsToIgnore 忽略该种异常,sentinel不进行流量拦截
@SentinelResource(value = "fallback",
fallback = "handlerFallback",blockHandler = "blockHandler", 
exceptionsToIgnore = {IllegalArgumentException.class})

OpenFeign

POM

<!--SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

激活Sentinel对Feign的支持

# 激活Sentinel对Feign的支持
feign:
  sentinel:
    enabled: true  

带@FeignClient注解的业务接口

/**
 * 使用 fallback 方式是无法获取异常信息的,
 * 如果想要获取异常信息,可以使用 fallbackFactory参数
 */
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)//调用中关闭9003服务提供者

PaymentFallbackService

@Component
public class PaymentFallbackService implements PaymentService
{
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
        return new CommonResult<>(444,"服务降级返回,没有该流水信息",new Payment(id, "errorSerial......"));
    }
}

Controller

//==================OpenFeign
@Resource
private PaymentService paymentService;

@GetMapping(value = "/consumer/openfeign/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
{
    if(id == 4)
    {
        throw new RuntimeException("没有该id");
    }
    return paymentService.paymentSQL(id);
}

主启动

@EnableFeignClients

多种熔断框架比较

在这里插入图片描述

规则持久化

配置

POM

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

YML

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

添加Nacos业务规则配置

在这里插入图片描述

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

刷新sentinel
重启服务后可能多次调用接口才会通过持久化验证

其他示例

摘自官网

自适应限流的示例

https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java

public class SystemGuardDemo {

    private static AtomicInteger pass = new AtomicInteger();
    private static AtomicInteger block = new AtomicInteger();
    private static AtomicInteger total = new AtomicInteger();

    private static volatile boolean stop = false;
    private static final int threadCount = 100;

    private static int seconds = 60 + 40;

    public static void main(String[] args) throws Exception {

        tick();
        initSystemRule();

        for (int i = 0; i < threadCount; i++) {
            Thread entryThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        Entry entry = null;
                        try {
                            entry = SphU.entry("methodA", EntryType.IN);
                            pass.incrementAndGet();
                            try {
                                TimeUnit.MILLISECONDS.sleep(20);
                            } catch (InterruptedException e) {
                                // ignore
                            }
                        } catch (BlockException e1) {
                            block.incrementAndGet();
                            try {
                                TimeUnit.MILLISECONDS.sleep(20);
                            } catch (InterruptedException e) {
                                // ignore
                            }
                        } catch (Exception e2) {
                            // biz exception
                        } finally {
                            total.incrementAndGet();
                            if (entry != null) {
                                entry.exit();
                            }
                        }
                    }
                }

            });
            entryThread.setName("working-thread");
            entryThread.start();
        }
    }

    private static void initSystemRule() {
        SystemRule rule = new SystemRule();
        // max load is 3
        rule.setHighestSystemLoad(3.0);
        // max cpu usage is 60%
        rule.setHighestCpuUsage(0.6);
        // max avg rt of all request is 10 ms
        rule.setAvgRt(10);
        // max total qps is 20
        rule.setQps(20);
        // max parallel working thread is 10
        rule.setMaxThread(10);

        SystemRuleManager.loadRules(Collections.singletonList(rule));
    }

    private static void tick() {
        Thread timer = new Thread(new TimerTask());
        timer.setName("sentinel-timer-task");
        timer.start();
    }

    static class TimerTask implements Runnable {
        @Override
        public void run() {
            System.out.println("begin to statistic!!!");
            long oldTotal = 0;
            long oldPass = 0;
            long oldBlock = 0;
            while (!stop) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                }
                long globalTotal = total.get();
                long oneSecondTotal = globalTotal - oldTotal;
                oldTotal = globalTotal;

                long globalPass = pass.get();
                long oneSecondPass = globalPass - oldPass;
                oldPass = globalPass;

                long globalBlock = block.get();
                long oneSecondBlock = globalBlock - oldBlock;
                oldBlock = globalBlock;

                System.out.println(seconds + ", " + TimeUtil.currentTimeMillis() + ", total:"
                    + oneSecondTotal + ", pass:"
                    + oneSecondPass + ", block:" + oneSecondBlock);
                if (seconds-- <= 0) {
                    stop = true;
                }
            }
            System.exit(0);
        }
    }
}

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

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

相关文章

轻松掌控视频速度,将过快变得慢慢来!

大家好&#xff01;在观看和编辑视频时&#xff0c;有时我们会遇到速度过快的视频&#xff0c;需要进行调整以获得更佳的观赏体验或编辑效果。为了让您轻松掌控视频速度&#xff0c;我们精心研发了一款强大的工具——视频速度调整器&#xff01;让您能够将过快的视频调慢&#…

相机SD卡数据丢失如何恢复?

出门在外&#xff0c;相机是人们记录生活点滴的重要工具&#xff0c;是旅游的最佳玩伴。人们每到一个地方&#xff0c;都喜欢用相机来见证自己来过的痕迹&#xff0c;拍好的照片都会被放到相机卡里&#xff0c;但在使用相机时&#xff0c;有时我们会意外删除了重要的照片或视频…

骨传导耳机对人体有危险吗?骨传导耳机的危害有哪些

根据目前的科学研究和经验&#xff0c;骨传导耳机被认为是相对安全的使用设备&#xff0c;不会对人体造成危险。由于骨传导耳机是通过振动颅骨传递声音&#xff0c;而不是通过直接传递声音到耳朵&#xff0c;因此对耳朵和听力系统的压力较小。 骨传导耳机相反没什么危害&#x…

【已解决】Windows10 pip安装报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x98

环境&#xff1a;win10, Python3.9 在Pycharm安装YoloV5的依赖包时出现报错&#xff1a;UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x98 出现 ‘gbk’ codec can’t decode… 的报错一般是因为读取文件出现编码问题导致没法读取文件&#xff0c;因此可以在报错…

Python基础 - 构造函数

目录 基础构造函数 重写 钻石继承 super函数 基础构造函数 命名为_init_&#xff0c;在实例化对象之前会自动执行该函数 构造函数方便我们在实例化对象的时候实现个性化定制 class A():def __init__(self,x,y):self.x xself.y ydef add(self):return self.xself.yclass…

找回宝塔面板登录信息

找回宝塔面板登录信息 找回面板信息 在Xshell控制面板中输入 /etc/init.d/bt default找回登录信息 在Xshell中输入 bt之后根据提示操作 bt 之后根据提示操作![在这里插入图片描述](https://img-blog.csdnimg.cn/e209039ef4684c8a92126d5b8a0580d6.png#pic_center)

软件测试 —— Airtest的iOS实用接口介绍 (建议收藏)

1. 前言 前段时间Airtest更新了1.3.0.1版本&#xff0c;里面涉及非常多的iOS功能新增和改动&#xff0c;今天想详细跟大家聊一下里面的iOS设备接口。 PS&#xff1a;本文示例均使用本地连接的iOS设备&#xff0c;Airtest版本为1.3.0.1 。 2. 安装接口&#xff1a;install、in…

PAT 1130 Infix Expression

个人学习记录&#xff0c;代码难免不尽人意。 Given a syntax tree (binary), you are supposed to output the corresponding infix expression, with parentheses reflecting the precedences of the operators. Input Specification: Each input file contains one test ca…

煤质软化:提升采矿效率的关键技术

煤质软化&#xff1a;提升采矿效率的关键技术 随着煤炭的广泛应用和能源需求的增长&#xff0c;对煤炭采矿和利用的要求也不断提高。传统的煤炭采矿方法往往面临一些困难和挑战&#xff0c;如厚层、高硬度以及强抗压性等问题&#xff0c;导致采掘效率低下、操作困难&#xff0c…

如何搭建接口自动化测试框架?

经过了一年多的接口测试工作&#xff0c;旧的框架也做了一些新的调整&#xff0c;删除了很多冗余的功能&#xff0c;只保留了最基本的接口结构验证、接口回归测试、线上定时巡检功能。 一、框架的演进 界面 UI 做了优化&#xff0c;整个框架的画风突然不一样了&#xff08;人…

1688API技术解析,实现按图搜索1688商品(拍立淘)

一种可能的解决方案是使用图像识别和相似度匹配的算法。您可以通过将输入的图片与1688上的商品图片进行比对&#xff0c;找出最相似的商品。这涉及到图像特征提取、相似度计算以及数据库匹配等技术。您可以使用开源的图像处理库&#xff08;如OpenCV&#xff09;来进行图像处理…

38. 连续签到领金币数

文章目录 题目需求思路一实现一题目来源 题目需求 用户每天签到可以领1金币&#xff0c;并可以累计签到天数&#xff0c;连续签到的第3、7天分别可以额外领2和6金币。 每连续签到7天重新累积签到天数。 从用户登录明细表中求出每个用户金币总数&#xff0c;并按照金币总数倒…

无涯教程-分类算法 - Python实现函数

为了在Python中实现SVM&#xff0c;无涯教程将从标准库导入开始&#xff0c;如下所示- import numpy as np import matplotlib.pyplot as plt from scipy import stats import seaborn as sns; sns.set() 接下来&#xff0c;从sklearn.dataset.sample_generator创建具有线性可…

材料空间「填空解谜」:MIT 利用深度学习解决无损检测难题

内容一览&#xff1a;材料检测在工程、科学及制造业中扮演着至关重要的角色。传统的材料检测方法&#xff0c;例如切割和化学试剂检测具有破坏性&#xff0c;同时较为耗费时间和资源。近期&#xff0c;MIT 科学家利用深度学习开发了一种技术&#xff0c;能够填补缺失信息&#…

迁移学习:实现快速训练和泛化的新方法

文章目录 迁移学习的原理迁移学习的应用快速训练泛化能力提升 迁移学习的代码示例拓展应用与挑战结论 &#x1f389;欢迎来到AIGC人工智能专栏~迁移学习&#xff1a;实现快速训练和泛化的新方法 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博…

服务网格实施周期缩短 50%,丽迅物流基于阿里云 ACK 和 ASM 的云原生应用管理实践

作者&#xff1a;王夕宁、 刘强、 华相 公司介绍 丽迅物流是百丽旗下专注于时尚产业、为企业提供专业物流及供应链解决方案的服务商。其产品服务主要包括城市落地配、仓配一体、干线运输及定制化解决方案。通过自研智能化物流管理平台&#xff0c;全面助力企业合作集约化发展…

C++中前置++和后置++的详细讲解

参考链接&#xff08;链接讲的很全&#xff09;&#xff1a;C前置和后置的区别 对于迭代器和其他模板对象使用前缀形式 (i) 的自增, 自减运算符.&#xff0c;理由是 前置自增 (i) 通常要比后置自增 (i) 效率更高。 class Age { public: Age& operator() //前置 {…

c++ std::ref

ref 对于函数式编程&#xff08;如 std::bind&#xff09;&#xff0c;是对参数直接拷贝&#xff0c;而不是引用&#xff0c;std::ref的引入就是为了解决一些传参问题 ref是个函数模板&#xff0c;用来构建一个reference_wrapper对象并返回&#xff0c;该对象拥有传入的elem变…

day-33 代码随想录算法训练营(19) 贪心part03

1005.K次取反后最大化的数组和 思路一&#xff1a;求出正负数的个数&#xff0c;根据k值来进行取反 134.加油站 思路&#xff1a;考虑总油量和当前剩余油量&#xff0c;同时遍历两个数组&#xff0c;当前剩余油量小于0时&#xff0c;说明在 i 之前都无法出发。 135.分发糖果 …

yml基本语法与支持的数据格式

一、yml基本语法 1、yml文件以缩进代表层级关系 2、缩进不允许使用tab只能使用空格 3、空格的个数不重要&#xff0c;只要相同层级的元素左对齐即可 4、大小写敏感 5、数据格式为&#xff0c;名称:(空格)值 二、yml支持的数据格式 1、对象&#xff1a;键值对的集合(key:…