Sentinel详解
文章目录
- 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控制台配置:
上面面对的问题:
- 没有体现我们自己的业务要求。
- 自定义的处理方法又和业务代码耦合在一块
- 每个业务方法都添加一个兜底代码膨胀加剧。
- 全局统一的处理方法没有体现。
对于这些问题 为此我们有了可以写一个类进行全局处理:
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详解相关推荐
- jedispool redis哨兵_Redis详解(九)------ 哨兵(Sentinel)模式详解
在上一篇博客----Redis详解(八)------ 主从复制,我们简单介绍了Redis的主从架构,但是这种主从架构存在一个问题,当主服务器宕机,从服务器不能够自动切换成主服务器,为了解决这个问题,我 ...
- 详解JVM内存管理与垃圾回收机制2 - 何为垃圾
随着编程语言的发展,GC的功能不断增强,性能也不断提高,作为语言背后的无名英雄,GC离我们的工作似乎越来越远.作为Java程序员,对这一点也许会有更深的体会,我们不需要了解太多与GC相关的知识,就能很 ...
- redis详解(四)-- 高可用分布式集群
一,高可用 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响. 停止服务的原因可能由于网卡.路由器.机房.CPU负载过高.内存溢出.自然灾害等不可预期的原 ...
- python循环语句-详解Python中的循环语句的用法
一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句 ...
- 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解
前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...
- python3 内置函数详解
内置函数详解 abs(x) 返回数字的绝对值,参数可以是整数或浮点数,如果参数是复数,则返回其大小. # 如果参数是复数,则返回其大小.>>> abs(-25) 25>> ...
- Java Spring Data Redis实战与配置参数详解 application.properties...
Redis作为开源分布式高并发缓存,使用范围非常广泛,主流互联网公司几乎都在使用. Java Spring Boot 2.0实战开发Redis缓存可以参考下面的步骤,Redis安装可以直接使用Linu ...
- SpringBoot的配置详解application
SpringBoot的配置文件application有两种文件格式,两种配置的内容是一致的,只是格式不一致. 1.application.properties 2.application.yml或者a ...
- [转]application.properties详解 --springBoot配置文件
本文转载:http://blog.csdn.net/lpfsuperman/article/details/78287265###; # spring boot application.propert ...
最新文章
- Java学习总结:27
- python 中文乱码问题解决方案
- js导航条 二级滑动 模仿块级作用域
- JDBC简单连接MySQL
- 使用 CodeIgniter 框架快速开发 PHP 应用(四)
- 转)Ubuntu安装teamviewer
- 【Java面试题】线程的生命周期包括哪几个阶段?
- 有关于fprintf()函数的用法
- python3lde下载_Python3.4IDE软件下载_Python3.4IDEAPP_Python3.4IDE手机版官方下载_Python3.4IDE1.8-华军软件园...
- 市场营销学3——市场营销环境
- 经典美文诵读2 If I Were a Boy Again假如我又回到了童年
- 从运维角度测试全局死锁以及带来的问题
- 基于Bootstrap的下拉框多选 Bootstrap Multiselect 插件使用
- Discuz3.4-SSRF-从触发点到构造payload
- 基于Maix IDE的编程环境 K21O人脸识别+串口输出
- python中列表的声明,查询,修改,删除 del 和添加 append,insert
- DEV C++编写程序出现 [errror]Id returned 1 exit status报错可能出现的原因及解决办法
- BTM 领涨「国产」公链,46支区块链概念股涨停
- DDD 实战 (5):战略设计之上下文映射和系统分层架构
- 积木报表—JimuReport v1.5.4版本发布,免费的可视化Web报表工具