(六)Spring Cloud Alibaba 2023.x:Sentinel 流量控制与熔断限流实现

发布于:2024-12-22 ⋅ 阅读:(173) ⋅ 点赞:(0)

目录

前言

准备

下载sentinel控制台

项目集成

引入依赖

配置yml文件

限流控制

Sentinel注解


前言

在微服务架构中,流量控制组件至关重要,它是保障系统稳定性与高可用性的核心手段之一 。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。

准备

  • jdk17+
  • maven3.9.4+
  • idea2023
  • spring cloud: 2023.0.1.0
  • spring cloud alibaba: 2023.0.1

源码获取:GitHub - RemainderTime/spring-cloud-alibaba-base-demo: 基于spring cloud alibaba生态快速构建微服务脚手架

下载sentinel控制台

本地运行sentinel控制台管理限流接口

本篇使用的版本:1.8.8

官方下载地址:Releases · alibaba/Sentinel

百度网盘:百度网盘 请输入提取码 提取码: 92h6

下载到本地就是一个jar包

在当前包文件夹中执行运行命令。端口号可自行更改

java -Dserver.port=8089 -Dcsp.sentinel.dashboard.server=localhost:8089 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.8.jar

启动成功访问http://127.0.0.1:8089/ 默认账号密码:sentinel

包含了sentinel本身的服务,已经博主已经配置启动完成的消费者生产者服务

项目集成

根据前面的博文,目前我们已经创建了三个微服务

引入依赖

每个服务都可能用到sentinel做限流,所以我们在父级pom.xml文件中引入sentinel依赖

<!-- 分布式限流降级组件 sentinel-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引入Transport 模块与 Sentinel 控制台进行通信 -->
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-transport-simple-http</artifactId>
  <version>1.8.8</version>
</dependency>

配置yml文件

对消费者和生产者的yml文件配置sentinel

本篇着重是对常用接口和方法进行流量控制,对于网关路由限流不是本篇重点,所以不配置网关服务的sentinel。

spring:
  application:
    name: http-cloud-producer
  cloud:
    sentinel: #流量控制中心
      transport:
        dashboard: localhost:8089 # sentinel-dashboard地址
        port: 8721
      eager: true
      filter:
        enabled: true

注意!!!

8721表示的是当前服务中Sentinel客户端与sentinel控制台通信的端口,如果存在多个服务使用sentinel,那么每个服务的端口不能重复。如果只有一台服务使用sentinel,不设置端口默认是8719,但是进入sentinel控制台我们会发现,控制台本身就将8719端口占用了。

所以我们自己的服务如果不指定端口,sentinel会按照启动的先后顺序在8719基础上+1来分配端口。

限流控制

首先启动sentinel控制台,再启动依次启动项目服务后

在sentinel控制台中,我们发现项目服务中都是白板什么也没有。

那是因为我们目前什么请求都没有操作,所以sentinel没有监听到任何数据。

请求上一篇为了验证seata组件实现的下单接口(因为两个服务的接口都会被调用)

回到sentinel控制台我们会看到生产者和消费者服务数据都有了

通过控制台的限流按钮,对相关接口进行限流操作

将阀值设置为0,再次请求下单接口,就会返回限流提示

Sentinel注解

sentinel提供了一个注解@SentinelResource 可以加到接口或者方法上特殊处理

@RestController
public class FeignController {

    @Autowired
    private SentinelService sentinelService;

    /**
     *   使用sentinel 限流熔断注解并集合使用feign远程调用
     * @return
     */
    @GetMapping(value = "/sentinelOrFeign")
    public String sentinelOrFeign() {
        return sentinelService.sentinelOrFeign();
    }

    /**
     *   使用sentinel 限流熔断注解  本地调用
     * @return
     */
    @GetMapping(value = "/sentinelLocal")
    public String sentinelLocal() {
        return sentinelService.sentinelLocal();
    }
}
@Service
public class SentinelService {

    @Autowired
    private FeignService feignService;

    @SentinelResource(value = "sentinelOrFeign", fallback = "fallbackHandler", fallbackClass = SentinelExceptionUtil.class,
                      blockHandler = "blockExHandler", blockHandlerClass = SentinelExceptionUtil.class)
    public String sentinelOrFeign(){

        return feignService.feignInfo01();
    }

    @SentinelResource(value = "sentinelLocal", fallback = "fallbackHandler", fallbackClass = SentinelExceptionUtil.class,
                      blockHandler = "blockExHandler", blockHandlerClass = SentinelExceptionUtil.class)
    public String sentinelLocal(){

        //        throw new RuntimeException("测试sentinel本地调用异常捕获");
        return "sentinel本地调用成功";
    }
}

注解属性说明:

value: 自定义限流名称,不自定义就是默认接口或方法名。

blockHandler : 该方法或接口触发限流后需要特殊处理的方法名。

blockHandlerClass : 方法实现的类class。

fallback : 该方法或接口除了限流异常外的其他异常触发后处理的方法名。

fallbackClass : 方法实现的类class。

自定义处理类 SentinelExceptionUtil.class 实现

public class SentinelExceptionUtil {

    /**
     * Sentinel 规则的 流控、熔断、热点参数限流 等被触发时调用。优先级高于 fallback
     * @param ex
     * @return
     */
    public static String blockExHandler(BlockException ex) {
        ex.printStackTrace();
        return "Sentinel 规则的 流控、熔断、热点参数限流 等被触发:" + ex.getMessage();
    }

    /**
     * 业务异常(如运行时异常)或其他未被 Sentinel 规则拦截的异常触发。
     * @param ex
     * @return
     */
    public static String fallbackHandler(Throwable ex) {
        ex.printStackTrace();
        return "业务异常或其他未被 Sentinel 规则拦截的异常触发: " + ex.getMessage();
    }
}

同样对上面定义的接口设置限流阀值为0,请求返回了我们处理后的内容

注意!!!

上一篇使用了seata作为分布式事务,使用注解@GlobalTransactional。

如果当前方法上使用了分布式事务,那么不能对该方法进行限流控制或者是加@SentinelResource特殊处理,这样会使分布式事务失效,以及这个分布式事务涉及到的被调用方的接口也不能限制(实测避坑)。如果一定要进行限流,可以对调用该方法的接口进行限流处理是没有问题的。


至此Spring Cloud alibaba集成Sentinel实现熔断限流完成了


网站公告

今日签到

点亮在社区的每一天
去签到