Spring Boot整合流控组件Sentinel的场景分析
作者:哪?吒 发布时间:2023-06-22 19:27:53
一、百度百科
Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
1、Sentinel 特性
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
2、Sentinel 的开源生态
二、Sentinel 的历史
2012 年,Sentinel 诞生,主要功能为入口流量控制。
2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
2018 年,Sentinel 开源,并持续演进。
2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出C++原生版本,同时针对 Service Mesh 场景也推出了Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
2020 年,推出Sentinel Go 版本,继续朝着云原生方向演进。
三、Sentinel 基本概念
1、资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
2、规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
四、sentinel的优势
友好的控制面板
支持实时监控
支持多种限流,比如QPS限流,线程数以及多种限流策略
支持多种降级模式,支持按平均返回时间降级,按多种异常数降级,按异常比例降级等
方便扩展开发,支持SPI模式对chain进行扩展
支持链路的关联,可以实现按链路统计限流,系统保护,热门资源保护等等
五、Sentinel 功能和设计理念
1、什么是流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
2、流量控制设计理念
流量控制有以下几个角度:
资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
运行指标,例如 QPS、线程池、系统负载等;
控制的效果,例如直接限流、冷启动、排队等。
Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。
3、什么是熔断降级
除了流量控制以外,及时对调用链路中的不稳定因素进行熔断也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,可能会导致请求发生堆积,进而导致级联错误。
Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
这里是引用Hystrix源自Netflix API团队于2011年开始的弹性工程工作。2012年Hystrix不断发展和成熟,Netflix内的许多团队都采用了它。如今,每天在Netflix执行数以千亿计的线程隔离和数以千计的信号隔离调用,这大大的提高了运行时间和弹性。
4、熔断降级设计理念
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。
Hystrix 通过线程池隔离的方式,来对依赖(在 Sentinel 的概念中对应 资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多),还需要预先给各个资源做线程池大小的分配,并且对于一些使用了 ThreadLocal 的场景来说会有问题(如 Spring 事务)。
Sentinel 对这个问题采取了两种手段:
(1)通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
(2)针对慢调用和异常对资源进行降级
除了对并发线程数进行控制以外,Sentinel 还可以根据响应时间和异常等不稳定因素来快速对不稳定的调用进行熔断。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新渐进式地恢复。
5、系统自适应保护
Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
6、Sentinel 是如何工作的
Sentinel 的主要工作机制如下:
对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。
7、竞品对比
六、SpringBoot整合sentinel
1、加入pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
2、编写sentinel规则
@PostConstruct
public void initFlowRules(){
//1.创建存放限流规则的集合
List<FlowRule> rules = new ArrayList<>();
//2.创建限流规则
FlowRule rule = new FlowRule();
//定义资源,表示sentinel会对这个资源生效
rule.setResource("helloSentinel");
//定义限流规则类型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//定义QPS每秒能通过的请求个数
rule.setCount(2);
//3.将限流规则放入集合中
rules.add(rule);
//4.加载限流规则
FlowRuleManager.loadRules(rules);
}
@GetMapping("/helloSentinel")
public String hello(){
try{
Entry entry = SphU.entry("helloSentinel");
return "helloSentinel success.";
}catch (Exception e){
log.error(e.getMessage());
return "helloSentinel error";
}
}
3、测试
(1)频率小于1秒两次时,访问成功
(2)频率大于1秒两次时,由于限流规则的设立,故失败
七、springboot整合sentinel dashboard
1、安装sentinel dashboard
(1)下载jar包
sentinel-1.7.1jar包下载链接
链接: https://pan.baidu.com/s/1MSwFNSaE_3gRxe6nsNXNDQ
提取码: e5j2
(2)启动jar包
java -Dserver.port=9000 -jar sentinel-dashboard.jar
2、springboot整合sentinel dashboard
(1)引入pom
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.7.2</version>
</dependency>
(2)配置启动类
-Dcsp.sentinel.dashboard.server=localhost:9000 -Dproject.name=GooReeyProject
(3)通过调用接口,使其在dashboard显示出来
3、用sentinel dashboard配置流控
(1)注释掉代码中的流控设置代码
(2)用控制台的配置取代代码
八、sentinel中其它定义资源的方式
1、抛出异常的方式定义资源
@GetMapping("/helloSentinel")
public String hello(){
try{
Entry entry = SphU.entry("helloSentinel");
return "helloSentinel success.";
}catch (Exception e){
log.error(e.getMessage());
return "helloSentinel error";
}
}
2、返回布尔值方式定义资源
代码示例:
@GetMapping("/sentinelBoolean")
public boolean sentinelBoolean(){
if(SphO.entry("sentinelBoolean")){
try {
log.info("sentinelBoolean success.");
return true;
}finally {
SphO.exit();
}
}else{
log.warn("sentinelBoolean error.");
return false;
}
}
3、sentinel支持异步调用链路的统计
在异步调用中,需要通过SphU.asynvEntry(xxx)方法定义资源,并通常需要在异步的回调函数中调用exit()方法。
代码编写:
(1)启动类加入@EnableAsync注解
@EnableDiscoveryClient
@SpringBootApplication(scanBasePackages = "com.guor")
@MapperScan("com.guor.management.dao")
@RefreshScope
@EnableAsync
public class ManagementApplication {
public static void main(String[] args) {
SpringApplication.run(ManagementApplication.class, args);
}
}
(3)控制层
@GetMapping("/sentinelAsync")
public void sentinelAsync(){
AsyncEntry asyncEntry = null;
try {
asyncEntry = SphU.asyncEntry("sentinelAsync");
userService.sentinelAsync();
log.info("sentinelAsync success.");
}catch (BlockException e){
log.error("sentinelAsync error.");
}finally {
if(asyncEntry != null){
asyncEntry.exit();
}
}
}
sentinel dashboard未定义时:
sentinel dashboard定义后:流控成功!
4、注解形式定义资源
(1)pom文件
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.7.2</version>
</dependency>
(2)配置类
package com.guor.management.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
@Configuration
public class SentinelAspectConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
return new SentinelResourceAspect();
}
}
(3)控制类
@SentinelResource(value = "sentinel_Annotation", blockHandler = "exceptionHandler")
@GetMapping("/annotation")
public String sentinelAnnotation(){
return "sentinelAnnotation";
}
public String exceptionHandler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后";
}
(4)定义流控规则
来源:https://blog.csdn.net/guorui_java/article/details/121730747
猜你喜欢
- 介绍什么是ThreadLocal?ThreadLocal叫做线程变量,用于在多线程环境下创建线程本地变量。通俗的讲,ThreadLocal可
- 本文主要介绍我为桌面和 Web 设计的一个超级秘密 Flutter 项目使用了画布和可拖动节点界面。本教程将展示我如何使用堆栈来使用小部件完
- 相比于直线检测,直线拟合的最大特点是将所有数据只拟合出一条直线void fitLine( InputArray points, Output
- 前言最近看插件库上少有的取色器大都是圆形的或者奇奇怪的的亚子,所以今天做两个矩形的颜色取色器提示:以下是本篇文章正文内容,下面案例可供参考一
- 1.map遍历快速实现边距,文字自适应改变大小Container( // padding: EdgeI
- 光流的概念是由一个叫Gibson的哥们在1950年提出来的。它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时
- 1.返回ModelAndView对象(.jsp)controller代码:package controller;import java.ut
- 1 自定义类加载器自定义类加载器的代码很简单,只需要继承ClassLoader类,覆写findClass方法即可其默认实现是会抛出一个异常:
- 逆时针画圆弧,原理:将360度分割成36份,分别标出每10度角度时的坐标点,然后将每个点连接起来。 #include <io
- 前言前面介绍了APP顶部导航栏AppBar,今天来介绍下Flutter实现APP底部导航栏。我们以仿写微信的底部导航栏来举例说明。要实现类似
- 概述:App几乎都离不开与服务器的交互,本文主要讲解了flutter网络请求三种方式 flutter自带的HttpClient、 第三方库h
- [LeetCode] 2. Add Two Numbers 两个数字相加You are given two non-empty&n
- 因为mybatis好使,所以几乎需要操作数据库的时候,我都会使用mybatis,而且在一个正式的项目中,同时存在BS和CS的程序,都使用的M
- 问题:在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码。原因其实很简单,就是系统的编码和程序的编码采用了不
- 前言之前我们提到了 CustomPaint er 的 Paint 可以使用渐变(GradientShader)来填充绘制的图形,本篇我们来介
- 背景在接口请求过程中,传递json对象,springboot转换为实体VO对象后,所有属性都为null。post请求:后台接收请求:当时就懵
- 双向顺序队列ArrayDeque和双向链式队列LinkedList,JDK已经包含,在此略。ArrayDeque包括顺序栈和顺序队列,Lin
- 一. 线性表中的顺序表线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见
- 目录前言使用自写代码预览完整代码使用第三个插件编码结论前言本文将带您了解在 Flutter 中制作翻转卡片动画的两个完整示例。第一个示例从头
- forward_list 概述forward_list 是 C++ 11 新增的容器,它的实现为单链表。forward_list 是支持从容