服务熔断保护实践--Sentinal
目录
概述
环境说明
步骤
Sentinel服务端
Sentinel客户端
依赖
在客户端配置sentinel参数
测试
保护规则设置
设置资源名
设置默认的熔断规则
RestTemplate的流控规则
Feign的流控规则
概述
微服务有很多互相调用的服务,构成一系列的调用链路,如果调用链路中某个服务失效或者网络堵塞等问题,而有较多请求都需要调用有问题的服务时,这是就会造成多个服务的大面积失效,造成服务“雪崩”效应。
服务“雪崩”的根本原因在于服务之间的强依赖,为了预防服务“雪崩”这一问题,可以做好服务隔离、服务熔断降级、服务限流。
服务隔离:当某个服务故障时,不波及其他模块,不影响整体服务。
服务熔断:当下游服务因为请求压力过大造成响应慢或响应失败时,上游服务为了保护系统,暂时切断对下游服务的调用,直接返回一个降级的内容,从而保全整体系统。
服务限流:限制系统的输入和输出达到保护系统的目的,例如:限制请求速率,超出的请求不处理或者暂缓处理或降级处理。
本文介绍的服务熔断组件是Sentinel
Sentinel和Hystrix的对比
| 对比项目 | Sentinel | Hystrix |
|---|---|---|
| 隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
| 熔断策略 | 基于响应时间或失败比例 | 基于失败比例 |
| 实时指标实现 | 滑动窗口 | 信号量隔离 |
| 规则配置 | 支持多种数据源 | 支持多种数据源 |
| 扩展性 | 多个扩展点 | 插件形式 |
| 基于注解的支持 | 支持 | 支持 |
| 限流 | 基于QPS,支持基于调用关系的限流 | 支持 |
| 流量整形 | 支持慢启动、匀速器模式 | 不支持 |
| 系统负载保护 | 支持 | 不支持 |
| 控制台 | 开箱即用,可配置规则、秒级监控、机器发现等 | 不完善 |
本文的操作是在 服务熔断保护实践--Hystrix 的基础上进行。
环境说明
jdk1.8
maven3.6.3
mysql8
spring cloud2021.0.8
spring boot2.7.12
idea2022
步骤
Sentinel服务端
下载Sentinel服务jar包
cmd进入jar包所在目录
使用java -jar命令启动
D:\soft\sentinel>java -jar sentinel-dashboard-1.8.6.jar
浏览器访问localhost:8080
输入用户名/密码:sentinel/sentinel

进入到Sentinel控制台

Sentinel客户端
依赖
在父工程声明spring-cloud-alibaba依赖(注意:在dependencyManagement里声明)
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.4.0</version><type>pom</type><scope>import</scope></dependency>

在sentinel客户端的服务(order-service、order-service-feign_hystrix) 引入sentinel依赖
<!--引入sentinel-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
刷新依赖
在客户端配置sentinel参数
application.yml配置sentinel服务控制台信息(涉及到的客户端都加,这里在order-service服务、order-service-feign_hystrix服务里加)
spring:cloud:sentinel:transport:dashboard: localhost:8080
测试
启动eureka、product、order-service、order-service-feign_hystrix服务

浏览器访问
http://localhost:9002/order/buy/1
http://localhost:9003/order/buy/1

查看sentinel控制台,首页下方看到两个服务

展开,访问子选项

浏览器多次访问服务,能看到实时监控如下

保护规则设置
在order-service服务中,新建一个Controller类,用于sentinel流控测试
由OrderController复制、修改得到Order1Controller
package org.example.order.controller;import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.example.order.entity.Product;
import org.example.order.feign.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/order1")
public class Order1Controller {@Autowiredprivate ProductFeignClient productFeignClient;@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){return productFeignClient.findById(id);}}
Order1Controller添加降级方法
/*** 定义降级逻辑* 熔断执行的降级方法*/public Product orderBlockHandler(Long id){Product product = new Product();product.setProductName("触发熔断的降级方法");return product;}/*** 定义降级逻辑* 抛出异常执行的降级方法*/public Product orderExceptionHandler(Long id){Product product = new Product();product.setProductName("抛出异常执行的降级方法");return product;}
在请求的方法上方添加@SentinelResource注解
/*** @SentinelResource* blockHandler: 声明熔断时执行的降级方法(限流熔断降级)* fallback: 抛出异常执行的降级方法(异常降级)*/@SentinelResource(blockHandler = "orderBlockHandler", fallback = "orderExceptionHandler")@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){return productFeignClient.findById(id);}
修改product服务的findById方法,注释掉模拟网络延迟的代码

启动eureka、product、order服务
多次访问order1接口方法
http://localhost:9002/order1/buy/1
浏览器访问Sentinel控制台
http://localhost:8080/#/dashboard/metric/service-order
看到实时监控数据如下

熟悉相关流控规则设置界面

点击如图+流控按钮添加流控规则,看到如下界面

点击+熔断按钮,看到如下界面

点击+热点按钮,看到如下界面

点击+授权按钮,看到如下界面

修改order-service服务Order1Controller类的findById方法,添加如下代码
if(id != 1){throw new RuntimeException("异常的id,抛出异常");}

重启order-service服务
浏览器访问
http://localhost:9002/order1/buy/1
刷新sentinel控制台
点击添加熔断规则



访问:正常访问
http://localhost:9002/order1/buy/1

访问:异常访问
http://localhost:9002/order1/buy/2

触发异常降级方法,按住Ctrl + R组合键,将异常访问次数超过设置阈值1
5s(熔断时长)内,访问id为正常值1,也返回的是异常降级方法

5s(熔断时长)后,访问id为正常值1,能正常访问了

设置资源名
资源名称默认为包名+类名+方法名

如何自定义资源名称?方法如下:
修改接口方法@SentinelResource添加value= "findById"设置
/*** @SentinelResource* blockHandler: 声明熔断时调用的降级方法* fallback: 抛出异常执行的降级方法* value: 自定义资源名称,默认 包名+类名+方法名*/@SentinelResource(value = "findById",blockHandler = "orderBlockHandler", fallback = "orderExceptionHandler")@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){
重启order服务

发现资源名称变为了自定义的findById
同时发现一个问题:在重启order服务后也清空了熔断规则问题

可以设置默认的熔断规则来解决这个问题。
设置默认的熔断规则
在order-service服务里配置默认的熔断规则
修改application.yml,添加如下sentinel的datasource配置
spring:cloud:sentinel:datasource:ds:file:file: classpath:flowrule.jsondata-type: jsonrule-type: flow
在resources目录下添加flowrule.json文件
[{"resource": "orderFindById","controlBehavior": 0,"count": 1,"grade": 1,"limitApp": "default","strategy": 0}
]
一条限流规则主要由下面几个因素组成:
resource:资源名,即限流规则的作用对象 count: 限流阈值 grade: 限流阈值类型(QPS 或并发线程数) limitApp: 流控针对的调用来源,若为 default 则不区分调用来源 strategy: 调用关系限流策略 controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)
这些值,可以参考RuleConstant.class,双击shift 搜索RuleConstant,找到RuleConstant.class
例如:
controlBehavior=0 代表为默认的流量控制 (直接拒绝或快速失败)
controlBehavior=1代码WARN UP(预热)

重启order服务
访问服务

查看Sentinel控制台,能看到默认的流控规则了。

设置默认的熔断规则总结:
通用的流控规则在方法上方添加注解@SentinelResource(value = "findById",blockHandler = "orderBlockHandler", fallback = "orderExceptionHandler"),同时编写对应的降级方法。
RestTemplate的流控规则
修改order服务
@LoadBalanced
@Bean
@SentinelRestTemplate(fallback = "handleFallback", fallbackClass = ExceptionUtil.class, blockHandler="handleBlock",blockHandlerClass=ExceptionUtil.class)
public RestTemplate restTemplate(){return new RestTemplate();
}

@SentinelRestTemplate说明
-
异常降级
-
fallback:异常降级方法
-
fallbackClass:异常降级类
-
-
限流降级
-
blockHandler:限流降级方法
-
blockHandlerClass:限流降级类
-
添加异常类
package org.example.order.exception;import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import org.example.order.entity.Product;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;public class ExceptionUtil {//限流熔断业务逻辑public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body,ClientHttpRequestExecution execution, BlockException ex) {System.err.println("Oops: " + ex.getClass().getCanonicalName());Product product = new Product();product.setProductName("限流熔断降级");return new SentinelClientHttpResponse(JSON.toJSONString(product));}//异常熔断业务逻辑public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body,ClientHttpRequestExecution execution, BlockException ex) {System.err.println("fallback: " + ex.getClass().getCanonicalName());Product product = new Product();product.setProductName("异常熔断降级");return new SentinelClientHttpResponse(JSON.toJSONString(product));}
}

查看sentinel配置,SentinelProperties.class

修改sentinel配置,使得SpringCloud应用启动时,直接与Sentinel建立心跳连接,访问sentinel 控制台就可以看到服务连接情况,不需要第一次访问应用的某个接口时,才连接sentinel。
spring.cloud.sentinel.eager = true

复制Order1Controller得到Order2Controller,修改代码后如下:
package org.example.order.controller;import org.example.order.entity.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
@RequestMapping("/order2")
public class Order2Controller {@Autowiredprivate RestTemplate restTemplate;@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)public Product findById(@PathVariable Long id){if(id != 1){throw new RuntimeException("异常的id,抛出异常");}return restTemplate.getForObject("http://service-product/product/1", Product.class);}
}
启动eureka、product、order服务
访问sentinel控制台,直接能看到服务

访问

添加流控规则



测试
访问1次,没有触发流控规则,能正常访问到数据
http://localhost:9002/order2/buy/1

多次访问,触发流控规则,调用了降级方法

控制台显示显示如下

确实是ExceptionUtil的信息

RestTemplate的流控规则总结:
-
RestTemplate的Bean上方添加注解
@SentinelRestTemplate -
添加异常处理的类
Feign的流控规则
在order-service-feign_hystrix服务修改
在feign中开启sentinel熔断
feign:# 在feign中开启hystrix熔断#circuitbreaker:# enabled: true# 在feign中开启sentinel熔断sentinel:enabled: true
配置FeignClient
和使用Hystrix的方式一致,需要配置FeignClient接口以及通过 fallback 指定熔断降级方法
启动eureka、product、order-service-feign_hystrix服务
测试
浏览器访问

查看sentinel控制台

添加流控规则

访问次数小于阈值,正常返回数据

多次访问超过阈值,触发了Feign熔断的降级方法

Feign的流控规则总结:
-
添加依赖
-
在feign中开启sentinel熔断支持
-
配置FeignClient接口及实现类里定义熔断方法
完成!enjoy it!
相关文章:
服务熔断保护实践--Sentinal
目录 概述 环境说明 步骤 Sentinel服务端 Sentinel客户端 依赖 在客户端配置sentinel参数 测试 保护规则设置 设置资源名 设置默认的熔断规则 RestTemplate的流控规则 Feign的流控规则 概述 微服务有很多互相调用的服务,构成一系列的调用链路…...
页面淘汰算法模拟实现与比较
1.实验目标 利用标准C 语言,编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法,并随机发生页面访问序列开展有关算法的测试及性能比较。 2.算法描述 1. 最佳淘汰算法(Op…...
FPGA实现HDMI转LVDS视频输出,纯verilog代码驱动,提供4套工程源码和技术支持
目录 1、前言免责声明 2、目前我这里已有的图像处理方案3、本 LVDS 方案的特点4、详细设计方案设计原理框图视频源选择静态彩条IT6802解码芯片配置及采集ADV7611解码芯片配置及采集silicon9011解码芯片配置及采集纯verilog的HDMI 解码模块奇偶场分离并串转换LVDS驱动 5、vivado…...
JAVA-easyexcel多sheet页导入
今天给宝子带来一套多sheet页导入的模板,话不多说直接上代码 String localFilePath "file.xlsx";JSONObject jsonObject JSON.parseObject(file);String useFile jsonObject.getString("file");useFileuseFile.replace("\\\\",&qu…...
Java——比较器(一文搞懂比较器Comparable和Comparator)
基于Comparable的接口类基于Comparator的接口类 1、比较器的Comparable接口类 Comparable类的定义: public interface Comparable<T>{ public int compareTo(T o); }2、Comparable比较器的返回值: 此方法返回一个int类型的数据,但是此int的值…...
企业直播招聘抖音报白如何实现?怎么样才能报白成功?
现在每天几亿人都在使用抖音等短视频平台进行娱乐或者工作学习,也有很多商家和企业利用抖音等短视频平台进行盈利和企业宣传相关的服务,其中比较典型的就是通过抖音直播等功能为自身企业进行招聘。 但是通过抖音等短视频平台进行招聘时,很多…...
【考研数学】概率论与数理统计 —— 第七章 | 参数估计(2,参数估计量的评价、正态总体的区间估计)
文章目录 一、参数估计量的评价标准1.1 无偏性1.2 有效性1.3 一致性 二、一个正态总体参数的双侧区间估计2.1 对参数 μ \mu μ 的双侧区间估计 三、一个正态总体的单侧置信区间四、两个正态总体的双侧置信区间写在最后 一、参数估计量的评价标准 1.1 无偏性 设 X X X 为总…...
【设计模式】第10节:结构型模式之“组合模式”
一、简介 组合模式:将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于࿰…...
改进YOLOv3!IA-YOLO:恶劣天气下的目标检测
恶劣天气条件下从低质量图像中定位目标还是极具挑战性的任务。现有的方法要么难以平衡图像增强和目标检测任务,要么往往忽略有利于检测的潜在信息。本文提出了一种新的图像自适应YOLO (IA-YOLO)框架,可以对每张图像进行自适应增强,以提高检测…...
Vue路由跳转的几种方式
1.this. $router.push( ) 跳转到指定的URL,在history栈中添加一个记录,点击后退会返回上一个页面。 1. 不带参数// 字符串this.$router.push(/home)this.$router.push(/home/first)// 对象this.$router.push({path:/home})this.$router.push({ path: /…...
TiDB x 汉口银行丨分布式数据库应用实践
汉口银行是一家城市商业银行,近年来专注科技金融、民生金融等领域。在数据库国产化改造中,汉口银行引入了 TiDB 数据库,并将其应用在重要业务系统:头寸系统中,实现了一栈式的数据服务,同时满足了高并发、低…...
uci机器学习数据库简介
UCI(University of California, Irvine)机器学习数据库是经过精心整理的、用于研究和开发机器学习算法的数据集合。UCI机器学习数据库是一个公开的、广泛使用的数据集合,它由加州大学欧文分校的计算机科学系维护。该数据库中包含了许多数据集…...
多人协作使用git如何解决冲突?
什么情况会产生冲突 git merge XXX(合并分支时的冲突): 当你尝试将一个分支的更改合并到另一个分支时,如果两个分支都修改了相同的文件的相同部分,Git 将无法自动解决冲突,因此会发生冲突。你需要手动解决这些冲突,然后…...
基于【逻辑回归】的评分卡模型金融借贷风控项目实战
背景知识: 在银行借贷过程中,评分卡是一种以分数形式来衡量一个客户的信用风险大小的手段。今天我们来复现一个评分A卡的模型。完整的模型开发所需流程包括:获取数据,数据清洗和特征工程,模型开发,…...
企业拉美跨境出海面对时延情况怎么办?
随着全球化不断发展,中国企业也不断向海外拓展业务,开拓市场,增加收入来源,扩大自身品牌影响力。然而出海企业面临不同以往的困难和挑战,在其中不可避免面临的跨境网络时延问题,如何选择区域进行部署企业业…...
【vector题解】只出现一次的数字 | 电话号码的数字组合
只出现一次的数字 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并…...
VS2022 开发方式
使用 C# 在VS 2022 上开发时,发现有多种项目类型可以创建。这些类型放一起容易搞混,于是记录一下各种类型的区别。 这里主要介绍windows控制台程序、MFC程序、WPF程序、WinForm程序的特点。 创建哪种应用? 创建控制台应用 Windows控制台程序…...
【Python语言速回顾】——数据可视化基础
目录 引入 一、Matplotlib模块(常用) 1、绘图流程&常用图 编辑 2、绘制子图&添加标注 编辑 3、面向对象画图 4、Pylab模块应用 二、Seaborn模块(常用) 1、常用图 2、代码示例 编辑 编辑 编辑 …...
java实现pdf文件添加水印,下载到浏览器
java实现pdf文件添加水印,下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …...
代码随想录算法训练营第四十一天丨 动态规划part04
01背包理论基础 见连接:代码随想录 416. 分割等和子集 思路 01背包问题 背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
OPENCV图形计算面积、弧长API讲解(1)
一.OPENCV图形面积、弧长计算的API介绍 之前我们已经把图形轮廓的检测、画框等功能讲解了一遍。那今天我们主要结合轮廓检测的API去计算图形的面积,这些面积可以是矩形、圆形等等。图形面积计算和弧长计算常用于车辆识别、桥梁识别等重要功能,常用的API…...
大模型智能体核心技术:CoT与ReAct深度解析
**导读:**在当今AI技术快速发展的背景下,大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术:CoT(思维链)和ReAct(推理与行动),这两种方法正在重新定义大模…...
[学习笔记]使用git rebase做分支差异化同步
在一个.NET 项目中,使用了Volo.Abp库,但出于某种原因,需要源码调试,因此,使用源码方式集成的项目做了一个分支archive-abp-source 其中引用方式变更操作的提交为:7de53907 后续,在master分支中…...
Steam爬取相关游戏评测
## 因为是第一次爬取Steam。所以作为一次记录发出;有所错误欢迎指出。 无时间指定爬取 import requests import time import csv import osappid "553850" # 这里你也可以改成 #appid int(input()) max_reviews 10000 # 想爬多少条 # max_reviews…...
