Sentinel详解_sentinel文档-程序员宅基地

技术标签: sentinel  java  数据库  

Sentinel是什么?

Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。

中文官网地址:https://sentinelguard.io/zh-cn/docs/introduction.html

Sentinel基本概念

以下来自Sentinel官网
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

什么是熔断降级

当调用链路中某个资源出现不稳定,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源。

sentinel处理这个问题采取了两中方式:

以下来自官网
1、通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。

2、通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

Sentinel的使用

注意:

在这里插入图片描述

1. 引入 Sentinel 依赖

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

2、下载Sentinel

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

在这里插入图片描述
下载完成后找到下载的目录并且在这个目录打开cmd窗口
在这里插入图片描述
使用Java -jar +名字启动
在这里插入图片描述

访问http://localhost:8080 登录账号密码均为sentinel
在这里插入图片描述

3、编写配置文件

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: '*' #开放全部的对外监控的节点

4、启动类

@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401
{
    
    public static void main(String[] args) {
    
        SpringApplication.run(MainApp8401.class, args);
    }
}

由于Sentinel采用的懒加载使用需要访问异常才可以在控制台显示。

5、流控规则

在这里插入图片描述

解释如下:
在这里插入图片描述

系统默认的流控规则(直接)例如:
在这里插入图片描述

它表示1秒钟内查询1次就是OK,若超过次数1,就直接-快速失败,报默认错误

关联
关联就是当关联的资源达到阈值时,就限流自己。
例如:
当与A关联的资源B达到阀值后,就限流A自己

在sentinel设置如下:
在这里插入图片描述
上图表示关联的资源testB的QPS访问次超过阈值1,就限流限流testA。

预热

什么是热启动?

来自官网
在这里插入图片描述

热启动最开始的阈值=阈值除以coldFactor(默认值为3)。默认coldFactor为3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

配置如下:
在这里插入图片描述

上图表示:
系统初始化的阀值为10 / 3 约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10

排队等待

注意:
匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。

此规则适用于消息队列

例如
在这里插入图片描述

6、降级规则

在这里插入图片描述

RT(平均响应时间,秒级)
平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级
窗口期过后关闭断路器
RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)

异常比列(秒级)
QPS >= 5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

异常数(分钟级)
异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

注意:
Sentinel的断路器是没有半开状态的这和Hystrix是不同的

RT(平均响应时间)使用配置例如

@GetMapping("/testD")
public String testD()
{
    
    //暂停几秒钟线程
    try {
     TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
     e.printStackTrace(); }
    log.info("testD 测试RT");
    return "------testD";
}

sentinel配置如下
在这里插入图片描述
上图表示平均响应时间超过0.2毫秒且时间窗口的请求数>=5,开启降级,等到时间窗口结束后,关闭降级。

异常比例配置 例如

这里是引用

 
@GetMapping("/testD")
public String testD()
{
    
    //暂停几秒钟线程
    try {
     TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
     e.printStackTrace(); }
    log.info("testD 测试RT");
    return "------testD";
}
 

sentinel配置如下:

在这里插入图片描述
上图表示
对testD的每秒访问数量中异常数量的占比超过20%且每秒的请求数量大于等于5,就开启降级。

异常数

这里是引用

异常数是按照分钟统计的

例如:

 
@GetMapping("/testE")
public String testE()
{
    
    log.info("testE 测试异常比例");
    int age = 10/0;
    return "------testE 测试异常比例";
}

配置:
在这里插入图片描述
自定义兜底方法
例如:

 
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "dealHandler_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1, 
                         @RequestParam(value = "p2",required = false) String p2){
    
    return "------testHotKey";
}
public String dealHandler_testHotKey(String p1,String p2,BlockException exception)
{
    
    return "-----dealHandler_testHotKey";
}
 
 
 sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
 
 
 
 

7、热点key限流

何为热点?
热点即经常访问的数据,很多时候我们希望统计或者限制某个热点数据中访问频次最高的TopN数据,并对其访问进行限流或者其它操作

前面的案列限流出问题后,都是用sentinel系统默认的提示:Blocked by Sentinel (flow limiting),这样对于用户体验其实并不好。

配置如下:
在这里插入图片描述
热点参数的注意点,参数必须是基本类型或者String

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

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

<?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">
    <parent>
        <artifactId>mscloud03</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloudalibaba-sentinel-service8401</artifactId>


    <dependencies>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件+actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

YML:

 
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719

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

controller;

package com.atguigu.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @auther zzyy
 * @create 2020-02-13 16:50
 */
@RestController
public class RateLimitController
{
    
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource()
    {
    
        return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
    }
    public CommonResult handleException(BlockException exception)
    {
    
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
    }
}

主启动类:

/**
 * @auther zzyy
 * @create 2019-12-09 18:49
 */
@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401
{
    
    public static void main(String[] args) {
    
        SpringApplication.run(MainApp8401.class, args);
    }
} 

配置流控规则:

在这里插入图片描述

图形配置和代码关系:
在这里插入图片描述
表示1秒钟内查询次数大于2,就跑到我们自定义的处流,限流返回了自己定义的限流处理信息

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

Controller:

/**
 * @auther zzyy
 * @create 2020-02-13 16:50
 */
@RestController
public class RateLimitController
{
    
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource()
    {
    
        return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
    }
    public CommonResult handleException(BlockException exception)
    {
    
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
    }

    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl()
    {
    
        return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
    }
}

Sentinel控制台配置:
在这里插入图片描述

上面面对的问题:

  1. 没有体现我们自己的业务要求。
  2. 自定义的处理方法又和业务代码耦合在一块
  3. 每个业务方法都添加一个兜底代码膨胀加剧。
  4. 全局统一的处理方法没有体现。

对于这些问题 为此我们有了可以写一个类进行全局处理:

CustomerBlockHandler(全局处理类)

public class CustomerBlockHandler
{
    
    public static CommonResult handleException(BlockException exception){
    
        return new CommonResult(2020,"自定义的限流处理信息......CustomerBlockHandler");
    }
}

controller :

@RestController
public class RateLimitController
{
    
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource()
    {
    
        return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
    }
    public CommonResult handleException(BlockException exception)
    {
    
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
    }

    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl()
    {
    
        return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
    }

    /**
     * 自定义通用的限流处理逻辑,
     blockHandlerClass = CustomerBlockHandler.class
     blockHandler = handleException2
     上述配置:找CustomerBlockHandler类里的handleException2方法进行兜底处理
     */
    /**
     * 自定义通用的限流处理逻辑
     */
    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handleException2")
    public CommonResult customerBlockHandler()
    {
    
        return new CommonResult(200,"按客户自定义限流处理逻辑");
    }

}

在这里插入图片描述

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_52090895/article/details/128048186

智能推荐

高级安卓开发面试题,史上最全的Android开发索引帖,Android开发两年-程序员宅基地

文章浏览阅读939次,点赞25次,收藏27次。由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

linux 使用 navicat 报错的各种问题_linux 安装navicat 提示报错-程序员宅基地

文章浏览阅读1.1k次。我是凝思系统,使用的一些系统库可能比较旧吧,容易报错,记录一下解决过程查阅资料是 glib 版本的问题[Solved]navicat report error after update system / Applications & Desktop Environments / Arch Linux Forums我用的是 glib 的 2.68.4 分支,旧的版本有些符号有问题https://github.com/GNOME/glib/tree/2.68.4参照 1_04_GLib库入门与实践_GLi_linux 安装navicat 提示报错

【Unity3D游戏开发实战】Unity3D实现休闲类游戏《2048》——算法、源代码_unity小游戏2048源码-程序员宅基地

文章浏览阅读1w次,点赞29次,收藏133次。推荐阅读CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群:1040082875大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。一、前言最近有粉丝要参加游戏创作大赛,问我需要准备学习什么知识,以及参加比赛的注意事项:参加这类比赛是非常有好处的,不仅提高了技术,也增长了见识。因为是兴趣驱动学习,在完善自己心爱游戏的过程中,要不断的去学习,不断的提高自己。更能在这个过程中找到志同道合的好朋友。那今天就._unity小游戏2048源码

【python】Open3D,Write PLY failed解决方法_write pcd failed: unable to generate header.-程序员宅基地

文章浏览阅读6.5k次。写了一个简单的函数,将三维点云(ndarray)保存为.ply文件:def save_points_as_ply(points, ply_path): """ 将点云保存为.ply文件,保存成功会打印'ply_path 已保存' :param points: ndarray, (-1,3) :param ply_path: str,'xxx/xxxx.ply' """ pcd = o3d.geometry.PointCloud() pcd.point_write pcd failed: unable to generate header.

详解 Android Views 元素的 layout_weight 属性-程序员宅基地

文章浏览阅读75次。所有View(视图)元素中都有一个XML属性android:layout_weight,其值为0,1,2,3...等整数值。使用了之后,其对应界面中的元素比例就会发生变化,变大或者变小。layout_weight属性其实就是一个元素重要度的属性,用于在线性布局中为不同的view元素设置不同的重要度。  所有的视图都有一个layout_weight值,其默认值为0,表示视图多大就占据..._android view获取当前的layout_with 的值

hosts文件修改后无法保存问题_linux hosts文件无法保存-程序员宅基地

文章浏览阅读8.6k次,点赞11次,收藏14次。hosts文件在windows目录下的位置(我的是win10系统,其他系统大同小异)C:\Windows\system32\drivers\etc\hostslinux系统hosts位置/etc/hostsLinux系统一般来说linux系统出现无法修改的情况是比较少的,基本没有,只要你处于root权限下是都可以修改的,因为root默认是有rwx权限的如果不能修改,r..._linux hosts文件无法保存

随便推点

详解:hive启动hiveserver2连JDBC报错:Could not open client transport with JDBC Uri 解决方案_could not open client transport with jdbc uri: jdb-程序员宅基地

文章浏览阅读4.4k次。hive启动hiveserver2连JDBC报错:Could not open client transport with JDBC Uri 解决方案 [hadoop@hadoop001 bin]$ ./beeline -u jdbc:hive2://hadoop001:10000/default -n hadoopls: cannot access /home/hadoop/app/spar..._could not open client transport with jdbc uri: jdbc:hive2://localhost:10000/

Sublime Text 3中文乱码问题的解决(最有效)_sublime text 显示乱码-程序员宅基地

文章浏览阅读2.2w次,点赞5次,收藏13次。 Sublime Text 3中文乱码问题的解决(最有效) Sublime Text 3是很好的代码编辑器,没有之一,因为她的性感高亮代码配色,更因为它的小巧,但是它默认不支持GBK的编码格式,因此打开GBK的代码文件,如果里面有中文的话,就会乱码,如下所示: 解决步骤如下: 大家如果是在官网下载的Sublime Text 3,那么首先需要安装一个 Pack..._sublime text 显示乱码

机器学习概述-程序员宅基地

文章浏览阅读5.2k次,点赞6次,收藏80次。机器学习是一种人工智能技术,通过对数据的学习和分析,让计算机系统自动提高其性能。简而言之,机器学习是一种从数据中学习规律和模式的方法,通过数据来预测、分类或者决策。_机器学习

操作系统安全---实验三:Windows7操作系统安全_操作系统的基本安全设置实验总结-程序员宅基地

文章浏览阅读3.8k次,点赞3次,收藏39次。目录一、实验目的及要求二、实验原理三、实验环境四、实验步骤及内容4.1账户与口令4.2审核与日志4.3安全模板五、实验总结六、分析与思考一、实验目的及要求了解Windows账户与密码的安全策略设置,掌握用户和用户组的权限管理、审核,以及日志的启用,并学会使用安全模版来分析配置计算机。二、实验原理Windows系列是目前世界上使用用户最多的桌面操作系统。由于历史原因,Windows的很多用户都直接以管理员权限运行系统,对计算机安全构成很大隐患。从Wi..._操作系统的基本安全设置实验总结

Python + Selenium自动化测试 -- 自定义Log类_selenium python 创建log类-程序员宅基地

文章浏览阅读3.2k次,点赞2次,收藏15次。本文用日志来记录我们测试脚本做的事情,其实最好的办法是写事件监听(对于小白的我,暂时不会,先从日志学起)。 下面写一个日之类,用来输出不同级别的日志信息到本地文件夹下的日志文件里。 目标输出效果: 解决思路: 1. 封装Log类,类名为Logger; 2. 在Logger类中创建记录器logger; 3. 创建一个handler,用于写入日志文件,写到磁盘;再创建一个handler,_selenium python 创建log类

canal 整合 springboot_canalboot-程序员宅基地

文章浏览阅读632次。mysql 开启bin_logvi /etc/my.cnf末尾增加如下配置log_bin=mysql-bin binlog-format=ROW #选择row模式server-id = 1expire_logs_days=5 #日志过期时间为5天 重启mysql [5.7]service mysqld restart 修改canal 配置vi canal/conf/canal.properties#唯一标识 新增canal.id =123 _canalboot