文章目录

  • Sentinel是什么?
  • **Sentinel基本概念**
  • 什么是熔断降级
  • Sentinel的使用
    • 注意:
  • 1. 引入 Sentinel 依赖
  • 2、下载Sentinel
  • **3、编写配置文件**
  • 4、启动类
  • **5、流控规则**
  • **6、降级规则**
  • **7、热点key限流**
  • **8、按资源名称限流+后续处理**
  • 9、按照Url地址限流+后续处理
  • 上面面对的问题:
  • 对于这些问题 为此我们有了可以写一个类进行全局处理:

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: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:#Nacos服务注册中心地址server-addr: localhost:8848sentinel:transport:#配置Sentinel dashboard地址dashboard: localhost:8080#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口port: 8719management: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: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard地址port: 8719management: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.classblockHandler = handleException2上述配置:找CustomerBlockHandler类里的handleException2方法进行兜底处理*//*** 自定义通用的限流处理逻辑*/@GetMapping("/rateLimit/customerBlockHandler")@SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handleException2")public CommonResult customerBlockHandler(){return new CommonResult(200,"按客户自定义限流处理逻辑");}}

Sentinel详解相关推荐

  1. jedispool redis哨兵_Redis详解(九)------ 哨兵(Sentinel)模式详解

    在上一篇博客----Redis详解(八)------ 主从复制,我们简单介绍了Redis的主从架构,但是这种主从架构存在一个问题,当主服务器宕机,从服务器不能够自动切换成主服务器,为了解决这个问题,我 ...

  2. 详解JVM内存管理与垃圾回收机制2 - 何为垃圾

    随着编程语言的发展,GC的功能不断增强,性能也不断提高,作为语言背后的无名英雄,GC离我们的工作似乎越来越远.作为Java程序员,对这一点也许会有更深的体会,我们不需要了解太多与GC相关的知识,就能很 ...

  3. redis详解(四)-- 高可用分布式集群

    一,高可用 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响. 停止服务的原因可能由于网卡.路由器.机房.CPU负载过高.内存溢出.自然灾害等不可预期的原 ...

  4. python循环语句-详解Python中的循环语句的用法

    一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句 ...

  5. 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解

    前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...

  6. python3 内置函数详解

    内置函数详解 abs(x) 返回数字的绝对值,参数可以是整数或浮点数,如果参数是复数,则返回其大小. # 如果参数是复数,则返回其大小.>>> abs(-25) 25>> ...

  7. Java Spring Data Redis实战与配置参数详解 application.properties...

    Redis作为开源分布式高并发缓存,使用范围非常广泛,主流互联网公司几乎都在使用. Java Spring Boot 2.0实战开发Redis缓存可以参考下面的步骤,Redis安装可以直接使用Linu ...

  8. SpringBoot的配置详解application

    SpringBoot的配置文件application有两种文件格式,两种配置的内容是一致的,只是格式不一致. 1.application.properties 2.application.yml或者a ...

  9. [转]application.properties详解 --springBoot配置文件

    本文转载:http://blog.csdn.net/lpfsuperman/article/details/78287265###; # spring boot application.propert ...

最新文章

  1. Java学习总结:27
  2. python 中文乱码问题解决方案
  3. js导航条 二级滑动 模仿块级作用域
  4. JDBC简单连接MySQL
  5. 使用 CodeIgniter 框架快速开发 PHP 应用(四)
  6. 转)Ubuntu安装teamviewer
  7. 【Java面试题】线程的生命周期包括哪几个阶段?
  8. 有关于fprintf()函数的用法
  9. python3lde下载_Python3.4IDE软件下载_Python3.4IDEAPP_Python3.4IDE手机版官方下载_Python3.4IDE1.8-华军软件园...
  10. 市场营销学3——市场营销环境
  11. 经典美文诵读2 If I Were a Boy Again假如我又回到了童年
  12. 从运维角度测试全局死锁以及带来的问题
  13. 基于Bootstrap的下拉框多选 Bootstrap Multiselect 插件使用
  14. Discuz3.4-SSRF-从触发点到构造payload
  15. 基于Maix IDE的编程环境 K21O人脸识别+串口输出
  16. python中列表的声明,查询,修改,删除 del 和添加 append,insert
  17. DEV C++编写程序出现 [errror]Id returned 1 exit status报错可能出现的原因及解决办法
  18. BTM 领涨「国产」公链,46支区块链概念股涨停
  19. DDD 实战 (5):战略设计之上下文映射和系统分层架构
  20. 积木报表—JimuReport v1.5.4版本发布,免费的可视化Web报表工具

热门文章

  1. [CentOS] 三、安装 i3
  2. 数据挖掘——时间序列算法之ARIMA模型
  3. 炼丹技巧----不断积累
  4. 外贸公司职业保密协议
  5. 整理这学期课程设计的人事管理系统
  6. Livox Lidar+海康Camera 基于loam的实时三维重建生成RGB彩色点云
  7. 二叉树的相关性质和特点
  8. 一套网络配置随时随地上网
  9. Pandas.Series转JSON
  10. av_image_get_buffer_size 与 av_image_fill_arrays