当前位置: 首页 > news >正文

从零搭建Cloud Alibaba (下) Sentinel篇

1.Sentinel控制台的安装

下载地址: 

Releases · alibaba/Sentinelx

下载后是一个jar包

进入目录

CMD命令

java -jar "sentinel-dashboard-1.8.8 .jar"

 如果发生了端口冲突则使用以下命令启动 修改端口号为8090

java  -Dserver.port=8090  -jar "sentinel-dashboard-1.8.8 .jar"

启动成功:

访问控制台

Sentinel Dashboard

账号密码默认都是sentinel

进入首页:

此时控制台已经安装完成

2.整合微服务

sentinel 的 starter 依赖:

将此sentinel依赖引入项目中

          <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>

yml配置:

spring:cloud:sentinel:transport:# 添加sentinel的控制台地址dashboard: 127.0.0.1:8090

如果是mvc的接口无需 @SentinelResource. 如果是业务方法, 需要 @SentinelResource

 @SentinelResource("hello")public String hello() {return "Hello Sentinel";}

@SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 hello 表示资源名。 @SentinelResource 还提供了其它额外的属性如 blockHandler,blockHandlerClass,fallback 用于表示限流或降级的操作,更多内容可以参考 Sentinel 注解支持。

启用feign对sentinel的支持:

#启用feign对sentinel的支持
feign:sentinel:enabled: true  # 启用 Sentinel 对 Feign 的支持

此时我们只需要访问集成服务中的任意一个路径就能在sentinel中查看到

2.1 sentinel限流(blockHandler) 讲解

2.1.1没有使用@SentinelResource注解(使用默认限流响应)

创建一个类用于测试限流

SentinelRatilimitConteroller

@RestController
@RequestMapping("/order/sentinelRatilimitConteroller")
public class SentinelRatilimitConteroller {/*** 测试sentinel限流 (没有添加@)* @return*/@GetMapping("/testSentinelRatilimitA")public String testSentinelRatilimitA() {return "没有达到限流的规则 --- 正常访问";}}

此时我们启动服务 访问地址

localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitA

能够正常访问

进入sentinel的控制台,给当前路径添加限流规则

当QPS超过1时的请求会快速失败返回默认的失败响应

此时限流返回到响应为默认的响应

2.1.2使用@SentinelResource注解自定义限流响应

写法1:

在controller中添加以下代码

    /*** 测试sentinel限流 (添加了@SentinelResource)* @SentinelResource value 为 限流规则的资源名称 blockHandler 为限流规则的异常处理方法*/@GetMapping("/testSentinelRatilimitB")@SentinelResource(value = "testSentinelRatilimitB",blockHandler = "testSentinelRatilimitBHandleException")public String testSentinelRatilimitB() {return "没有达到限流的规则 --- 添加了@SentinelResource 正常访问";}/***作为(testSentinelRatilimitB)的限流异常返回方法*/public String testSentinelRatilimitBHandleException(BlockException e) {return "限流了 --- 添加了@SentinelResource 异常处理";}

* @SentinelResource value 为 限流规则的资源名称 blockHandler 为限流规则的异常处理方法

     使得方法testSentinelRatilimitB 触发限流时 返回 testSentinelRatilimitBHandleException方法

正常访问:localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitB

添加限流规则:
 

快速访问:

执行了自定义限流处理

对应关系图

写法2:(推荐)

如果需要独立设置一个 限流类还可以这样写

添加一个新的controller

指定了blockHandler类中的指定方法作为限流处理

    @GetMapping("/testSentinelRatilimitC")@SentinelResource(value = "testSentinelRatilimitC",blockHandlerClass = OrderBlockHandler.class,// 限流异常返回方法所在类blockHandler = "testSentinelRatilimitC") //指定限流异常返回方法public String testSentinelRatilimitC() {return "没有达到限流的规则 --- 添加了@SentinelResource 默认异常处理";}

访问localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitC

为他编写一个类 和方法 (方法必须被 pblic static 修饰

public class OrderBlockHandler {// 必须是public static方法// 参数和返回类型要与原方法一致,最后加一个BlockException参数public static String testSentinelRatilimitC(BlockException ex) {return "触发限流了";}}

设置限流规则

快速访问:

2.2异常处理(fallback)

为一个接口配置 @SentinelResource(value = "testSentinelRatilimitD",

fallback = "testSentinelRatilimitDfallback")

fallback属性表示当前方法遇到异常会调用指定的方法

    @GetMapping("/testSentinelRatilimitD/{id}")@SentinelResource(value = "testSentinelRatilimitD",blockHandler = "testSentinelRatilimitDBlockHandler",fallback = "testSentinelRatilimitDfallback")public String testSentinelRatilimitD(@PathVariable("id") Integer id) {if (id == 0){throw new RuntimeException("id 不能为0");}return "没有达到限流的规则 --- id为"+ id;}//作为限流 处理public String testSentinelRatilimitDBlockHandler(@PathVariable("id") Integer id,BlockException e) {return "已触发限流 --- id为"+ id;}//作为 熔断 降级 异常处理public String testSentinelRatilimitDfallback(@PathVariable("id") Integer id,Throwable e) {return "触发率异常处理,传入id为:"+ id;}

2.2.1测试限流

访问地址:localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitD/1

为他设置限流规则:

多次访问:

触发限流规则,走了BlockHandler 所配置的方法

2.2.2测试异常

访问

http://localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitD/0

传入id值为0,我们设置id为0时会抛出异常,看看是否会走fallback所配置的方法

成功触发fallback

3.热点参数限流

在我们比如商城服务中的商品流量是不均匀的,我们可能要对同一个接口的不同参数进行限流

例如

在查询某个商品信息时,同样根据商品id进行查询商品,商品ID: 1:华为 2:小米 3:苹果

查询接口

queryPhone(int id);

传入id为1的量较大,那么我们就需要对id为1的商品进行限流,如图:

写一个方法:

    /*** 热点参数限流*/@GetMapping("/testSentinelRatilimitE/{id}")@SentinelResource(value = "testSentinelRatilimitE",blockHandler = "testSentinelRatilimitEBlockHandler")public String testSentinelRatilimitE(@PathVariable("id") int id){return "没有触发限流传入id为:"+ id;}/*** 热点参数限流处理*/public String testSentinelRatilimitEBlockHandler(int id,BlockException ex){return "触发限流处理,传入id为:"+ id;}

访问 :localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitE/0

参数索引: 写0时则为接口中的第一个参数

索引为0

统计窗口:表示*秒内统计的量

表示这个接口 带上参数ID时 QPS达到1开始限流

访问接口:localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitE/0

触发了限流

参数例外项:

例如当我们传入id为1时,我们的限流规则变成QPS为3才进行限流

上面的参数表示,当带参数索引为0时,限流QPS为1 ,参数例外项:当参数索引0 传入值为1 时,限流阈值QPS提升为3才限流

务必要点击添加按钮

测试发现id等于1时 ,只有QPS达到3才会触发限流

4.sentinel规则持久化(不会因为微服务重启丢失配置)

我们服务配置完成后,我们的微服务重启会导致我们这个服务的所有的配置丢失,不可能每重启一次我们就重新配置一次限流规则,所以需要持久化,持久化到哪里呢? 我们会选择持久化到配置中心 nacos中 

在服务中引入新的Maven坐标

<!--sentinel持久化-->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改yml配置

配置ds1 ds2 ds3 分别代表(流控规则)(熔断降级规则) (热点参数规则)的持久化配置

我们以流控规则作为演示

打开nacos创建对应的配置文件

内容:

[{"resource": "testSentinelRatilimitE","limitApp": "default","grade": 1,"count": 1,"strategy": 0,"controlBehavior": 0,"clusterMode": false}
]
// [
//   {
//     // 🔹【资源名称】你想保护的是哪个接口或功能?
//     // 这里是:testSentinelRatilimitE
//     // 代码中要用 SphU.entry("testSentinelRatilimitE") 来标记这个资源
//     "resource": "testSentinelRatilimitE",//     // 🔹【限流对象】对谁限流?
//     // "default" 表示:所有人都一样,一视同仁
//     // 你也可以写成 "appA"、"appB",实现不同应用不同策略
//     "limitApp": "default",//     // 🔹【限流方式】按什么标准限流?
//     // 1 = 按每秒请求数(QPS)来限
//     // 0 = 按并发线程数来限(不常用)
//     "grade": 1,//     // 🔹【限流阈值】最多允许多少流量?
//     // 这里是:每秒最多 1 个请求
//     // 超过第 1 个就直接拒绝,不让进
//     "count": 1,//     // 🔹【限流策略】怎么判断要不要限?
//     // 0 = 直接对自己限流(最简单常用)
//     // 1 = 当另一个资源被限流时,我也跟着限(关联限流)
//     // 2 = 只对某个调用链路限流(比如 A 调 B 才限)
//     "strategy": 0,//     // 🔹【触发限流后怎么办?】
//     // 0 = 立刻拒绝,抛出“被限流”错误(快速失败)
//     // 1 = 先预热,慢慢放行(适合突发流量)
//     // 2 = 排队等待,一个一个处理(削峰填谷)
//     "controlBehavior": 0,//     // 🔹【是单机还是集群?】
//     // false = 每台机器独立限流(单机模式,适合大多数场景)
//     // true = 多台机器共享一个总限流值(需要额外配置集群)
//     "clusterMode": false
//   }
// ]

!!!!非常非常难用,需要自己手动写json用于配置持久化,Sentinel控制台配置成为摆设,因为控制台上写的配置不会持久化,必须自己写!!!!

同样是阿里巴巴的产品 Nacos比sentinel好用太多了!

重启 当前服务

​​​​​​​

访问localhost:8082/order/sentinelRatilimitConteroller/testSentinelRatilimitE/1

nacos 配置限流规则成功

来到sentinel控制台查看限流规则

成功从nacos中读取限流规则

5.Sentinel集成OpenFeign实现fallback熔断降级

往公共API模块中引入sentinel maven 依赖

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

在api接口中添加fallbackFactory属性并创建对应的类

创建

StockApiFallback.class
@Component
public class StockApiFallback implements FallbackFactory<stockApi> {@Overridepublic stockApi create(Throwable cause) {return new stockApi() {@Overridepublic ResultData<String> reduceInventory() {throw new RPCException("201","调用库存服务调用失败");}@Overridepublic Integer reduceStock() {throw new RPCException("201","调用库存服务调用失败");}};}}

在fallback 的时候为了保证fallback后全局事务还能正常的回滚,fallback一般抛出自定义异常让事务回滚,并且全局异常处理器 处理整形后才返回给用户

自定义异常类:

@Data
public class RPCException extends RuntimeException{private String code;private String message;private Object data;public RPCException(String code,String message,Object data) {super(message);this.message = message;this.code = code;this.data =data ;}public RPCException(String code,String message) {super(message);this.message = message;this.code = code;}}

自定义异常捕获

@RestControllerAdvice
@Slf4j
public class RPCExceptionHandler {// 拦截自定义业务异常@ExceptionHandler(RPCException.class)public ResultData handleBizException(RPCException e) {log.warn("远程调用异常: code={}, msg={}", e.getCode(), e.getMessage());return ResultData.fail(e.getCode(),"系统出现错误,请稍后再试"); // 通常返回 200,业务码区分}}

重点:!!!!   然后在调用者模块 配置文件中开启OpenFeign 支持Sentinel

feign:sentinel:enabled: true  # 启用 Sentinel 对 Feign 的支持

,然后重新启动 测试全局事务回滚是否正常

发现系统出现异常后,使用的是全局异常处理器返回的消息

并且,事务全部正确回滚

任务完成

http://www.dtcms.com/a/316327.html

相关文章:

  • VUE-第二季-02
  • Sentinel全面实战指南
  • 制作一款打飞机游戏85:Hyper模式
  • JavaScript:Proxy 代理
  • 【数据结构初阶】--排序(三):冒泡排序,快速排序
  • 编码器模型和解码器模型解析
  • MongoDB学习专题(一)介绍安装基本操作
  • ✨OpenVoice 全流程实战:多语言语音合成系统安装与使用教程(附踩坑经验)
  • Makefile工具、双向链表
  • xshell、xftp使用案例
  • 【2025年8月5日】将运行一段时间的单机MongoDB平滑迁移至副本集集群
  • java回顾八股文中想起的知识点
  • 为什么不用rocketmq直接发送,用StreamBridge
  • 使用Playwright MCP探索网站并编写测试
  • 解锁n8n:开启自动化工作流的无限可能
  • 面试题:vue3使用proxy相较于vue2的优点在哪里
  • 03-基于深度学习的钢铁缺陷检测-yolo11-彩色版界面
  • postman接口测试实战
  • 鸿蒙组件装饰器深度解析:@Component vs @ComponentV2
  • 【实时Linux实战系列】基于实时Linux的智能交通系统设计
  • 数据结构---Makefile 文件(格式、文件变量、调用、伪目标)、gcc编译的四个步骤、双向链表(概念、作用、应用)
  • 若依vue前端处理日期数据的格式问题(只留下年月日,去掉时分秒)
  • 小易的yolo学习笔记2
  • AlexNet训练和测试FashionMNIST数据集
  • 系统启动项管理工具对美国服务器性能基线的验证标准
  • Rust进阶-part4-智能指针2
  • 真正的多模态上下文学习需要关注视觉上下文
  • 人工智能领域、图欧科技、IMYAI智能助手2025年1月更新月报
  • 【RabbitMQ】高级特性—消息确认详解
  • 轻量应用服务器Centos系统上安装jdk8和Jdk17教程(详细)