Springboot整合 Spring Cloud Alibaba Sentinel

1.Sentinel介绍

官方文档地址:
https://sentinelguard.io/zh-cn/docs/introduction.html
https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件。通过流控规则限制流量速率与并发,熔断规则依据异常比例/异常数或慢调用比例触发服务熔断,热点规则针对高频参数实施精细化限流,系统规则基于系统负载(如CPU、内存)动态调控流量以保障整体稳定性。

流控规则(阈值类型:QPS/并发线程数,阈值数值,模式:直接/关联/链路,效果:快速失败/Warm Up/排队等待)、熔断规则(策略:慢调用比例/异常比例/异常数。设置最大RT【最大响应时间】/比例阈值/熔断时长/最小请求数/统计时长)、热点规则(参数级QPS阈值及例外配置)和系统规则(LOAD/CPU/平均RT等全局阈值触发自适应限流),实现多维度流量管控与系统稳定性保障。

2.下载Sentinel控制台

注:根据版本关系选择Sentinel版本
https://sca.aliyun.com/docs/2023/overview/version-explain/?spm=5176.29160081.0.0.748065cbd69hSu
控制台下载地址:https://github.com/alibaba/Sentinel/releases
本人Spring Cloud Alibaba版本是 2023.0.0.0-RC1所以选择Sentinel版本为sentinel-dashboard-1.8.6.jar

在这里插入图片描述

3.启动Sentinel控制台

通过命令:java -jar .\sentinel-dashboard-1.8.6.jar
默认端口为8080
访问控制台http://localhost:8080/#/login。 账密默认为sentinel/sentinel

启动日志:

在这里插入图片描述
在这里插入图片描述

设置端口为8088 以及 修改账密为 test/123456 启动Sentinel
Powershell窗口
java ‘-Dserver.port=8088’ ‘-Dsentinel.dashboard.auth.username=test’ ‘-Dsentinel.dashboard.auth.password=123456’ -jar .\sentinel-dashboard-1.8.6.jar

cmd窗口
java -Dserver.port=8088 -Dsentinel.dashboard.auth.username=test -Dsentinel.dashboard.auth.password=123456 -jar D:\sentinel\sentinel-dashboard-1.8.6.jar

启动日志:
在这里插入图片描述

更多控制台配置项可查看地址: https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0
在这里插入图片描述

也可以写一个bat批处理文件,双击运行,不用每次都写命令:

在这里插入图片描述

在这里插入图片描述

4.整合Sentinel

1.引入SpringCloud Alibaba sentinel依赖

<dependencies>
    <!-- SpringCloud Alibaba sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
</dependencies>

2.添加yml配置,为项目模块设置sentinel控制台地址
配置好之后,先访问项目模块中的一个接口然后可在Sentinel控制台中查看

spring:
  application:
    name: @artifactId@
  profiles:
    active: ${profiles.active}
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
    sentinel:
      transport:
        dashboard: 127.0.0.1:8088
        web-context-unify: false #流控模式为链路时将调用链路放开,不进行默认收敛

在这里插入图片描述

5.Sentinel控制台规则介绍

1)实时监控

查看每个接口QPS信息
在这里插入图片描述

2)簇点链路

实时的去拉取指定客户端(显示到sentinel控制台的服务)接口的运行情况。它一共提供两种展示模式:一种用树状结构展示资源的调用链路,另外一种则不区分调用链路展示资源的实时情况。
注意: 簇点链路监控是内存态的信息,它仅展示启动后调用过的资源。

3)流控规则(flow control)

监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
应用场景:应对洪峰流量:秒杀,大促,下单,订单回流处理,付费场景,Api Gateway 网关。
通常会在服务提供端进行流控。

3.1)QPS

每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。

设置每秒超过2个请求便进行流控:
在这里插入图片描述

多余的请求被流控:
在这里插入图片描述

自定义流控信息:
@SentinelResource注解介绍:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

@GetMapping("/testUser")
    @SentinelResource(value = "testUser",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult user() {
        AjaxResult ajax = AjaxResult.success();
        return ajax;
    }
public class BlockHandler {

    public static AjaxResult flowBlockHandler(BlockException blockException){
        AjaxResult ajax = AjaxResult.error("服务器繁忙,请稍后再试");
        return ajax;
    }

}

流控信息如下:
在这里插入图片描述

3.2)并发线程数

并发数控制通常在调用端进行配置。
用于保护业务线程池不被慢调用耗尽。Sentinel并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝。
QPS设置1和并发线程数设置为1区别:
QPS:每秒请求数为1。
并发线程数:当我第一个请求进来,如果一直在处理中,没有响应。其他请求会被排除。等第一个请求处理完了,其他才会进来。

在这里插入图片描述

接口处理逻辑睡眠2s钟:

@GetMapping("/testUser")
    @SentinelResource(value = "testUser",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult user() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        AjaxResult ajax = AjaxResult.success();
        return ajax;
    }

流控信息如下:
在这里插入图片描述

3.3)流控模式

基于调用关系的流量控制。调用关系包括调用方、被调用方;一个方法可能会调用其他方法,形成一个调用链路的层次关系。

直接:接口调用达到设置的阈值后直接被流控抛出异常。

关联:当两个接口之间具有资源争抢或者依赖关系的时候,这两个接口便有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写的速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db和write_db这两个资源分别代表数据库读写,我们可以给read_db设置限流规则来达到写优先的目的。

准备两个方法:写方法addTest、读方法getTest

	@GetMapping("/addTest")
    @SentinelResource(value = "addTest",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult addTest() {
        AjaxResult ajax = AjaxResult.success();
        return ajax;
    }

    @GetMapping("/getTest")
    @SentinelResource(value = "getTest",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult getTest() {
        AjaxResult ajax = AjaxResult.success();
        return ajax;
    }

如果addTest 接口每秒钟访问超过2次,则对getTest 进行限流。
在这里插入图片描述

借助JMeter进行测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当JMmeter执行addTest时,访问getTest。会发现getTest被流控。
在这里插入图片描述

链路:根据调用链路入口限流。
当一个业务方法被多个请求调用,可以通过配置该方法使某一个请求进行流控。

addTest 调用testFun
getTest 调用testFun

@Component
public class SysLoginService {
	@SentinelResource(value = "testFun",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult testFun(){
        return AjaxResult.success("业务方法");
    }
}
	@GetMapping("/addTest")
    @SentinelResource(value = "addTest",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult addTest() {
        return loginService.testFun();
    }

    @GetMapping("/getTest")
    @SentinelResource(value = "getTest",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult getTest() {
        return loginService.testFun();
    }

在这里插入图片描述

对testFun方法资源进行设置,当每秒钟超过2次调用该方法资源,则对addTest进行流控。
在这里插入图片描述

addTest被流控:

在这里插入图片描述

getTest都可以正常访问:
在这里插入图片描述

3.4)流控效果

快速失败:默认的流控效果,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException,这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

Warm Up(激增流量):即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过“冷启动”让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
冷加载因子:codeFactor默认为3,即请求QPS从threshold(阈值)/3开始,经预热时长逐渐升至设定的QPS阈值。

以下配置指:5秒钟后才会一次性接受10个请求:
在这里插入图片描述

多测几组会发现 结果会在设定的【预热时长】基础上加个2s左右。

第一组测试结果:
在这里插入图片描述

第二组测试结果:
在这里插入图片描述

在这里插入图片描述

排队等待(脉冲流量):会严格控制请求通过的间隔时间,即让请求以均匀的速度通过。
主要用于处理间隔性突发的流量,例如消息队列,在某一秒有大量的请求到来,而接下来的几秒钟则处于空闲状态。我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
注:暂不支持QPS > 1000的场景。

通过JMeter模拟脉冲流量

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试结果:拒绝的QPS都为0,表明在超时时间5s内,所有的QPS都被处理。
在这里插入图片描述

进一步验证:同样的JMeter设置,改变流控效果,设置为快速失败,会发现每秒钟超过5个请求的被流控。

在这里插入图片描述

在这里插入图片描述

4)熔断降级

通常在服务消费端进行配置。

熔断降级官方介绍地址:https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7
概述:
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

4.1)熔断策略

慢调用比例:选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

最大RT:单位ms,当前资源接口允许的最大响应时间,大于当前设置的时间,就属于慢调用。
比例阈值:出现慢调用的比例(0-1之间),比如设置为0.1表示,10次请求出现一次就会熔断。
熔断时长:进入熔断状态的时长(单位s)。熔断时长过完之后,熔断器进入半开状态,如果再次请求响应时间大于设置的最大 RT,直接进入熔断状态。
最小请求数:最少请求的次数。
统计时长:单位ms,在这个时长之内请求的数目。

测试:在统计时长1s请求10次,如果出现1次慢调用则进入熔断。熔断时长为10s。
在这里插入图片描述

接口睡眠3s:

@GetMapping("/testUser")
    @SentinelResource(value = "testUser",blockHandlerClass = {BlockHandler.class},blockHandler = "flowBlockHandler")
    public AjaxResult user() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        AjaxResult ajax = AjaxResult.success();
        return ajax;
    }

通过JMeter进行测试:
猜想:JMeter请求10次,在浏览器中进行第11次调用,此时会进入熔断。10s后会进行一次请求并成功,但再次请求会直接熔断。
在这里插入图片描述

验证结果如下:
10次都请求成功
在这里插入图片描述

当我在浏览器请求第11次:
在这里插入图片描述

10s过后请求一次:请求成功
在这里插入图片描述

再进行一次请求:直接熔断
在这里插入图片描述

异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

比例阈值:出现异常的比例(0-1之间),比如设置为0.1表示,10次请求出现一次异常就会熔断。
熔断时长:进入熔断状态的时长(单位s)。熔断时长过完之后,熔断器进入半开状态,如果再次请求还是报异常,直接进入熔断状态。
最小请求数:最少请求的次数。
统计时长:单位ms,在这个时长之内请求的数目。

和慢调用比例一样的测试方法。只是java方法体内抛出的是异常,这里就不进行测试记录了。

异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

异常数:出现异常的次数。
熔断时长:进入熔断状态的时长(单位s)。熔断时长过完之后,熔断器进入半开状态,如果再次请求还是报异常,直接进入熔断状态。
最小请求数:最少请求的次数。
统计时长:单位ms,在这个时长之内请求的数目。

和异常比例一样的测试方法。只是将比例换成了次数。这里就不进行测试记录了。

5)整合OpenFeign进行降级

当服务消费者 调用 服务提供者的时候,如果服务提供者发生异常,对这个服务提供者进行降级处理。

前提:nacos/sentinel/openfeign依赖都已添加。

1.yml配置文件开启OpenFeign对Sentinel的支持。

#openfeign整合sentinel
feign:
  sentinel:
    enabled: true

2.添加OpenFeign接口的fallback实现类,这个类必须实现OpenFeign的接口。
在这里插入图片描述

3.在OpenFeign接口的@FeignClient中添加fallback配置,并指向该OpenFeign接口的fallback实现类。
在这里插入图片描述

4.在服务提供者方法体中加入异常代码

@RequestMapping(value = "/feignIgnore/selectUserByUserName", method = RequestMethod.GET)
public SysUser selectUserByUserName(@RequestParam(value = "userName") String userName) {
    int a = 1/0;
    return userService.selectUserByUserName(userName);
}

测试结果:断点进入降级方法。
在这里插入图片描述

6)热点规则

热点参数限流官方地址:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
在一个接口当中,某个参数的某些值访问量大,其他的值访问量平缓,这样可以针对某些访问量大的值进行流控。

以下配置为:id为5 和 6 这两个值,当每秒访问超过2次则进行限流。其他的值在每秒访问超过10次才会限流。
在这里插入图片描述

测试结果:
在这里插入图片描述
在这里插入图片描述

其他值:在第11次时被流控。
在这里插入图片描述

7)系统规则(兜底防护方案)

热点参数限流官方地址:https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81
Sentinel 系统自适应过载保护从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

当遇到规则难配,强弱依赖难梳理时结合系统指标和服务容量,自适应动态调整流量。

系统规则支持以下的模式:
Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
CPU 使用率:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

无需指定资源,直接在系统规则模块进行添加:
在这里插入图片描述

8)规则持久化

Spring Cloud Alibaba学习笔记》其实是阿里的微服务解决方案,是阿里巴巴结合自身微服务实践,开源的微服务全家桶,在Spring Cloud项目中孵化成为Spring Cloud的子项目。第一代的Spring Cloud标准中很多组件已经停更,如:Eureak,zuul等。所以Spring Cloud Alibaba很有可能成为Spring Cloud第二代的标准实现,所以许多组件在业界逐渐开始使用,已有很多成功案例。值得一提的是Spring Cloud Alibaba对Dubbo做了很好的兼容,同时也提供了一些强大的功能,如 Sentinel 流控 ,Seata 分布式事务,Nacos 服务发现与注册等等。 但现在网上学习SpringCloudAlibab的资料要么不全要么很少,完整的就更别说了,所以今天给大家免费分享的正是Alibaba出品的Spring Cloud Alibaba 的学习文档,图文并茂,量身打造,非常适合再学习Spring Cloud Alibaba的朋友观看!下面来看看这份Spring Cloud Alibaba 学习文档吧. Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。 为什么使用Spring Boot?很简单,我仅仅只需要非常少的几个配置就可以迅速方便的搭建起来一套 Web 项目或者是构建一个微服务! 本文档主要介绍了Spring Boot 框架快速入门教程以大量示例讲解了 Spring Boot 在各类情境中的应用,让读者可以跟着笔者的思维和代码快速理解并掌握。感兴趣的可以了解一下
### Spring Boot 整合 Spring Cloud Alibaba 示例教程 #### 项目准备 为了成功整合Spring BootSpring Cloud Alibaba,需先准备好开发环境。推荐使用的工具版本如下: - JDK 17 - Spring Boot 3.0.13 - Spring Cloud 2022.0.2 - Spring Cloud Alibaba 2022.0.0.0 - Nacos 2.3.0 (用于配置管理和服务发现)[^2] #### 创建基础工程结构 创建一个新的 Maven 或 Gradle 项目,在`pom.xml`文件中引入必要的依赖项。 对于Maven构建工具而言,可以在`pom.xml`加入以下内容来添加所需依赖: ```xml <dependencyManagement> <dependencies> <!-- Spring Cloud Alibaba --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Other dependencies... --> </dependencies> </dependencyManagement> ``` #### 配置Nacos作为注册中心 在应用启动类上通过注解方式开启对Nacos的支持,并设置相应的属性以便连接至Nacos服务器实例。 ```java @SpringBootApplication @EnableDiscoveryClient public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 同时修改`application.properties`或`yaml`中的相应配置以指向本地或其他位置运行着的Nacos Server地址: ```properties spring.application.name=demo-service spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 ``` #### 使用Sentinel实现限流降级功能 除了基本的服务治理能力外,还可以借助于阿里巴巴开源组件——Sentinel来进行流量控制以及熔断保护等功能扩展。只需简单地向POM文件追加sentinel-spring-cloud-starter即可快速集成此特性。 ```xml <!-- Sentinel Starter --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-core</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> ``` 完成上述操作之后便可以利用内置API定义资源并指定对应的规则了。 #### 实现服务间通信(RPC调用) 当多个微服务之间存在相互依赖关系时,则可通过Feign客户端发起远程过程调用来简化编码工作量;另外也可以考虑采用RabbitMQ这样的消息队列中间件来异步处理业务逻辑[^4]。 例如下面这段代码展示了如何在一个名为`user`的服务里声明一个接口去消费其他提供者暴露出来的HTTP API端点: ```java @FeignClient(name="order-service") public interface OrderService { @GetMapping("/orders/{id}") ResponseEntity<OrderDTO> getOrderById(@PathVariable Long id); } ``` 以上就是关于如何将Spring BootSpring Cloud Alibaba相结合的一些最佳实践建议,希望能够帮助读者更好地理解和掌握这套技术栈的应用场景与发展潜力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值