目录
前言
一、什么是Sentinel?
Sentinel 的主要特性
Sentinel 的开源生态
二、Sentinel的核心功能
三、Sentinel 的主要优势与特性
1、丰富的流控规则
2、完善的熔断降级机制
3、实时监控和控制台
4、多数据源支持
5、扩展性强
四、Sentinel 与 Hystrix 的对比
五、Sentinel安装与使用
1、Sentineal 控制台下载与安装
2、给服务接入sentinel监控
3、流控规则
接口限流
直接流控模式
关联流控模式
链路流控模式
主要概念
使用场景
4、@SentinelResource注解
基本用法
使用示例
注意事项
总结
前言
随着微服务架构的普及,如何保证系统的高可用性和稳定性成为开发者必须面对的重要课题。阿里巴巴开源的 Sentinel 作为一款流量防护组件,提供了熔断、限流、降级等多种功能,帮助开发者提升系统的容错能力。本文将记录 Sentinel 的核心功能及其在 Spring Cloud 中的集成和使用。也希望本文,能够帮助你们在微服务项目中轻松地集成和使用 Sentinel,提升系统的稳定性和容错能力。
一、什么是Sentinel?
Sentinel 是阿里巴巴开源的流量防护组件,专注于流量控制和系统稳定性保护。它提供了丰富的功能,如限流、熔断降级、系统自适应保护、实时监控等,帮助开发者构建高可用和高稳定性的微服务系统。
中文官网:home | Sentinel (sentinelguard.io)
Sentinel 的主要特性
Sentinel 的开源生态
二、Sentinel的核心功能
限流:通过多种流量控制策略,实现对热点数据、分布式请求等的限流。
熔断降级:根据调用错误比例、RT(响应时间)等指标,对不稳定的服务进行熔断,避免级联故障。
系统自适应保护:根据系统的负载情况,动态调整限流和熔断策略,保证系统在高负载下的稳定性。
实时监控:提供实时的监控与报警功能,帮助开发者及时发现和处理问题。
三、Sentinel 的主要优势与特性
1、丰富的流控规则
流量整形:支持匀速排队、预热、并发等多种流控策略。
热点参数限流:针对传入参数进行热点数据的限流保护。
系统自适应保护:根据系统的负载情况,动态调整限流和熔断策略。
2、完善的熔断降级机制
基于错误比例:在指定时间窗口内,如果请求的错误比例超过阈值,则触发熔断。
基于响应时间:在指定时间窗口内,如果请求的平均响应时间超过阈值,则触发熔断。
3、实时监控和控制台
实时监控:提供对实时流量、调用关系、链路流量等多维度的监控。
控制台:通过可视化的 Dashboard,实时配置和管理限流、熔断规则。
4、多数据源支持
规则动态更新:支持从 Nacos、Apollo、ZooKeeper 等多个数据源动态加载和更新规则。
5、扩展性强
SPI 扩展:提供 SPI 扩展点,可以自定义流控、熔断、降级等策略。
四、Sentinel 与 Hystrix 的对比
特性 | Sentinel | Spring Cloud Hystrix |
---|---|---|
限流 | 提供丰富的限流策略,如预热、匀速排队、并发控制等 | 不支持 |
熔断机制 | 支持基于错误比例、响应时间、异常数量等多种熔断策略 | 主要基于错误比例和响应时间 |
实时监控 | 提供完整的实时监控和可视化控制台 | 需要集成 Turbine 和 Hystrix Dashboard |
规则动态配置 | 支持多种数据源(如 Nacos、Apollo、ZooKeeper)动态配置规则 | 通过 Archaius 实现,灵活性相对较低 |
扩展性 | 提供丰富的 SPI 扩展点,方便自定义策略 | 扩展性相对较差 |
社区活跃度 | 社区活跃,持续更新 | 2018 年 Netflix 宣布进入维护模式,社区活跃度降低 |
依赖 | 轻量级,无需依赖额外组件 | 需要依赖 Hystrix Dashboard 和 Turbine 进行监控 |
Sentinel 和 Spring Cloud Hystrix 都是优秀的服务保护工具,但各有特点。Sentinel 提供了更丰富的限流策略、动态规则配置和实时监控功能,并且具有更高的扩展性。相比之下,Hystrix 在熔断和降级方面也有较好的表现,但由于Hystrix进入维护模式,其社区活跃度和新特性支持有所降低。
在选择时,可以根据具体需求和项目特点进行权衡。如果需要更强的限流能力、动态规则配置和实时监控,建议选择 Sentinel。如果项目已经使用 Hystrix 并且稳定运行,也可以继续使用 Hystrix。
五、Sentinel安装与使用
1、Sentineal 控制台下载与安装
下载地址:Releases · alibaba/Sentinel (github.com)
选择jar包下载
通过CMD命令运行
java -jar sentinel-dashboard-1.8.8.jar
如下图所示,则已启动成功。
访问地址:localhost:8080
账号密码:都是sentinel
2、给服务接入sentinel监控
引入依赖
<!-- sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>${spring-cloud-alibaba.version}</version>
</dependency>
如果版本不对的话,运行会报错,sentinel依赖时与web依赖形成循环依赖。
附上完整的maven依赖
<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><!-- spring boot --><spring-boot.version>2.7.5</spring-boot.version><!-- spring cloud --><spring-cloud.version>2021.0.1</spring-cloud.version><spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version><spring-cloud-starter-alibaba-nacos-config.version>2.1.4.RELEASE</spring-cloud-starter-alibaba-nacos-config.version>
</properties>
配置sentinel
server:port: 9090spring:application:name: demo-usercloud:nacos:discovery:server-addr: 192.168.1.85:8848namespace: democonfig:server-addr: 192.168.1.85:8848prefix: ${spring.application.name}file-extension: ymlnamespace: demosentinel:transport:dashboard: localhost:8080 #配置sentinel dashboard地址
重启服务,访问接口localhost:9090/hello/getOrder
这时候在控制台就可以看到我们的请求了,证明已经监控到我们服务
3、流控规则
流控规则属性
资源名: 唯一名称,默认请求路径,表示对该资源进行流控
针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
阈值类型/单击阈值:
QPS:(每秒钟的请求数量):当调用该api的QPS达到阈值时,进行限流
线程数:当调用该线程数达到阈值的时候,进行限流
是否集群:不需要集群
流控模式:
直接: api达到限流条件时,直接限流
关联: 当关联的资源达到阈值时,就限流自己
链路: 只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
流控效果:
快速失败: 直接失败,抛异常
Warm Up: 根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFctor,经过预热时长,才达到设置的QPS阈值
排队等待: 匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
接口限流
直接流控模式
新增流控规则
资源名指的是我们的接口地址,QPS设置为1,其他都选择默认值。保存后,我们测试接口调用。
第一次请求是正常响应的。
接下来我们快速请求接口,一秒钟点击多次
发现已经被限流了。
关联流控模式
当关联的资源达到阈值时,就限流自己,也就是说关联的资源(接口),QPS为1时,一秒内被多次请求的时候,自己的接口就会被限流。
如图所示,hello/addOrder 接口并发请求,hello/getOrder接口就被限流了。
链路流控模式
链路流控模式(Chain Mode)是 Sentinel 提供的一种流控模式,主要用于控制资源在特定调用链路上的访问频率。与一般的直接流控模式不同,链路流控模式通过定义调用链路来实现更细粒度的流量控制。这对于复杂的分布式系统中,尤其是微服务架构中,控制不同调用路径的流量非常有用。
主要概念
在链路流控模式下,流控规则会对特定的调用链路进行控制。调用链路通常由一个入口资源和一个目标资源组成,表示从入口资源到目标资源的一条特定调用路径。
使用场景
同一资源多入口:当一个资源可以通过多个入口访问时,可以针对不同入口设置不同的流控规则。
细粒度流控:对于某些关键资源,可以根据不同的调用链路进行更细粒度的流量控制,从而实现精细化管理。
示例:
假设有一个系统,其中有一个服务 orderService,它可以通过两个不同的入口资源 getOrder 和 getOrder2 被调用。我们希望限制通过 getOrder2 入口对 orderService 的调用频率。
4、@SentinelResource注解
@SentinelResource 是 Sentinel 提供的一个注解,用于定义资源并为其配置流控、熔断等规则。在方法上使用 @SentinelResource 注解,可以实现对该方法的流控、降级以及异常处理等功能。
基本用法
@SentinelResource 的基本属性包括 value、blockHandler、fallback 等。以下是它的常用属性及使用示例:
1. value(必填)
描述: 指定资源名称。该名称将作为 Sentinel 的资源标识,用于进行流控和降级保护。
类型: String
2. blockHandler
描述: 指定当资源被流控(如限流、降级)时的处理方法。该方法必须与原方法在同一个类中,或者在公共类中。方法签名要求一致,并且最后一个参数必须是 BlockException。
类型: String
3. blockHandlerClass
描述: 指定 blockHandler 所在类。如果 blockHandler 方法不在同一个类中,可以通过 blockHandlerClass 指定类。
类型: Class<?>
4. fallback
描述: 指定当资源执行发生异常时的处理方法。方法签名要求与原方法一致,或者额外带一个 Throwable 类型的参数用于接收异常。
类型: String
5. fallbackClass
描述: 指定 fallback 所在类。如果 fallback 方法不在同一个类中,可以通过 fallbackClass 指定类。
类型: Class<?>
6. defaultFallback
描述: 指定通用的默认降级方法,当未指定 fallback 方法或 fallback 方法不可用时,调用此方法。方法必须是静态的,且返回类型与原方法一致。
类型: String
7. exceptionsToIgnore
描述: 指定不会触发 fallback 处理的异常列表。
类型: Class<? extends Throwable>[]
8. exceptionsToTrace
描述: 指定会触发 fallback 处理的异常列表。默认情况下,所有的异常都会触发 fallback。
类型: Class<? extends Throwable>[]
使用示例
示例1:
在这个示例中,当访问 /hello 接口时,若触发了流控规则,handleBlock 方法会被调用返回处理结果。helloResource指的就是流控规则的资源名
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@GetMapping("/hello")@SentinelResource(value = "helloResource", blockHandler = "handleBlock")public String hello() {return "Hello, Sentinel!";}public String handleBlock(BlockException ex) {return "请求已被阻止!";}
}
示例2:
当 /test 接口在执行过程中抛出异常时,会调用 fallbackMethod 方法进行处理。
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class FallbackController {@GetMapping("/test")@SentinelResource(value = "testResource", fallback = "fallbackMethod")public String test() {if (Math.random() > 0.5) {throw new RuntimeException("出错");}return "成功";}public String fallbackMethod(Throwable ex) {return "Fallback: " + ex.getMessage();}
}
示例3:
在这个例子中,当资源触发流控时,将调用 ExternalHandler 类中的 externalBlockHandler 方法进行处理。
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ExternalHandlerController {@GetMapping("/external")@SentinelResource(value = "externalResource", blockHandler = "externalBlockHandler", blockHandlerClass = ExternalHandler.class)public String external() {return "这是个示例";}
}class ExternalHandler {// 必须为静态方法public static String externalBlockHandler(BlockException ex) {return "请求已被阻止";}
}
注意事项
blockHandler 和 fallback 方法的签名要求: 这些方法必须和原方法签名一致,blockHandler 方法额外需要接收一个 BlockException 参数,而 fallback 方法可以选择性地接收一个 Throwable 参数。
defaultFallback: 作为全局降级处理方法,必须是 public static 方法,并且参数和返回类型与原方法一致。
处理类的类加载顺序: 如果使用 blockHandlerClass 或 fallbackClass 指定外部类,这些类必须在项目启动时能够被加载。
总结
本文介绍了 Sentinel 的核心功能及其在 Spring Cloud 中的集成和使用。Sentinel 提供了丰富的流量控制和系统保护功能,帮助开发者提升系统的容错能力和稳定性。希望通过本文的学习,能够帮助你更好地理解和使用 Sentinel,提升微服务项目的稳定性和容错能力。