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

服务熔断保护实践--Sentinal

目录

概述

环境说明

步骤

Sentinel服务端

Sentinel客户端

依赖

在客户端配置sentinel参数

测试

保护规则设置

设置资源名

设置默认的熔断规则

RestTemplate的流控规则

Feign的流控规则


概述

微服务有很多互相调用的服务,构成一系列的调用链路,如果调用链路中某个服务失效或者网络堵塞等问题,而有较多请求都需要调用有问题的服务时,这是就会造成多个服务的大面积失效,造成服务“雪崩”效应。

服务“雪崩”的根本原因在于服务之间的强依赖,为了预防服务“雪崩”这一问题,可以做好服务隔离、服务熔断降级、服务限流。

服务隔离:当某个服务故障时,不波及其他模块,不影响整体服务。

服务熔断:当下游服务因为请求压力过大造成响应慢或响应失败时,上游服务为了保护系统,暂时切断对下游服务的调用,直接返回一个降级的内容,从而保全整体系统。

服务限流:限制系统的输入和输出达到保护系统的目的,例如:限制请求速率,超出的请求不处理或者暂缓处理或降级处理。

本文介绍的服务熔断组件是Sentinel

Sentinel和Hystrix的对比

对比项目SentinelHystrix
隔离策略信号量隔离线程池隔离/信号量隔离
熔断策略基于响应时间或失败比例基于失败比例
实时指标实现滑动窗口信号量隔离
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件形式
基于注解的支持支持支持
限流基于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的流控规则 概述 微服务有很多互相调用的服务&#xff0c;构成一系列的调用链路&#xf…...

页面淘汰算法模拟实现与比较

1.实验目标 利用标准C 语言&#xff0c;编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法&#xff0c;并随机发生页面访问序列开展有关算法的测试及性能比较。 2.算法描述 1. 最佳淘汰算法&#xff08;Op…...

FPGA实现HDMI转LVDS视频输出,纯verilog代码驱动,提供4套工程源码和技术支持

目录 1、前言免责声明 2、目前我这里已有的图像处理方案3、本 LVDS 方案的特点4、详细设计方案设计原理框图视频源选择静态彩条IT6802解码芯片配置及采集ADV7611解码芯片配置及采集silicon9011解码芯片配置及采集纯verilog的HDMI 解码模块奇偶场分离并串转换LVDS驱动 5、vivado…...

JAVA-easyexcel多sheet页导入

今天给宝子带来一套多sheet页导入的模板&#xff0c;话不多说直接上代码 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比较器的返回值&#xff1a; 此方法返回一个int类型的数据&#xff0c;但是此int的值…...

企业直播招聘抖音报白如何实现?怎么样才能报白成功?

现在每天几亿人都在使用抖音等短视频平台进行娱乐或者工作学习&#xff0c;也有很多商家和企业利用抖音等短视频平台进行盈利和企业宣传相关的服务&#xff0c;其中比较典型的就是通过抖音直播等功能为自身企业进行招聘。 但是通过抖音等短视频平台进行招聘时&#xff0c;很多…...

【考研数学】概率论与数理统计 —— 第七章 | 参数估计(2,参数估计量的评价、正态总体的区间估计)

文章目录 一、参数估计量的评价标准1.1 无偏性1.2 有效性1.3 一致性 二、一个正态总体参数的双侧区间估计2.1 对参数 μ \mu μ 的双侧区间估计 三、一个正态总体的单侧置信区间四、两个正态总体的双侧置信区间写在最后 一、参数估计量的评价标准 1.1 无偏性 设 X X X 为总…...

【设计模式】第10节:结构型模式之“组合模式”

一、简介 组合模式&#xff1a;将一组对象组织成树形结构&#xff0c;将单个对象和组合对象都看做树中的节点&#xff0c;以统一处理逻辑&#xff0c;并且它利用树形结构的特点&#xff0c;递归地处理每个子树&#xff0c;依次简化代码实现。使用组合模式的前提在于&#xff0…...

改进YOLOv3!IA-YOLO:恶劣天气下的目标检测

恶劣天气条件下从低质量图像中定位目标还是极具挑战性的任务。现有的方法要么难以平衡图像增强和目标检测任务&#xff0c;要么往往忽略有利于检测的潜在信息。本文提出了一种新的图像自适应YOLO (IA-YOLO)框架&#xff0c;可以对每张图像进行自适应增强&#xff0c;以提高检测…...

Vue路由跳转的几种方式

1.this. $router.push( ) 跳转到指定的URL&#xff0c;在history栈中添加一个记录&#xff0c;点击后退会返回上一个页面。 1. 不带参数// 字符串this.$router.push(/home)this.$router.push(/home/first)// 对象this.$router.push({path:/home})this.$router.push({ path: /…...

TiDB x 汉口银行丨分布式数据库应用实践

汉口银行是一家城市商业银行&#xff0c;近年来专注科技金融、民生金融等领域。在数据库国产化改造中&#xff0c;汉口银行引入了 TiDB 数据库&#xff0c;并将其应用在重要业务系统&#xff1a;头寸系统中&#xff0c;实现了一栈式的数据服务&#xff0c;同时满足了高并发、低…...

uci机器学习数据库简介

UCI&#xff08;University of California, Irvine&#xff09;机器学习数据库是经过精心整理的、用于研究和开发机器学习算法的数据集合。UCI机器学习数据库是一个公开的、广泛使用的数据集合&#xff0c;它由加州大学欧文分校的计算机科学系维护。该数据库中包含了许多数据集…...

多人协作使用git如何解决冲突?

什么情况会产生冲突 git merge XXX(合并分支时的冲突)&#xff1a; 当你尝试将一个分支的更改合并到另一个分支时&#xff0c;如果两个分支都修改了相同的文件的相同部分&#xff0c;Git 将无法自动解决冲突&#xff0c;因此会发生冲突。你需要手动解决这些冲突&#xff0c;然后…...

基于【逻辑回归】的评分卡模型金融借贷风控项目实战

背景知识&#xff1a; 在银行借贷过程中&#xff0c;评分卡是一种以分数形式来衡量一个客户的信用风险大小的手段。今天我们来复现一个评分A卡的模型。完整的模型开发所需流程包括&#xff1a;获取数据&#xff0c;数据清洗和特征工程&#xff0c;模型开发&#xff0c…...

企业拉美跨境出海面对时延情况怎么办?

随着全球化不断发展&#xff0c;中国企业也不断向海外拓展业务&#xff0c;开拓市场&#xff0c;增加收入来源&#xff0c;扩大自身品牌影响力。然而出海企业面临不同以往的困难和挑战&#xff0c;在其中不可避免面临的跨境网络时延问题&#xff0c;如何选择区域进行部署企业业…...

【vector题解】只出现一次的数字 | 电话号码的数字组合

只出现一次的数字 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给你一个整数数组 nums&#xff0c;其中恰好有两个元素只出现一次&#xff0c;其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并…...

VS2022 开发方式

使用 C# 在VS 2022 上开发时&#xff0c;发现有多种项目类型可以创建。这些类型放一起容易搞混&#xff0c;于是记录一下各种类型的区别。 这里主要介绍windows控制台程序、MFC程序、WPF程序、WinForm程序的特点。 创建哪种应用&#xff1f; 创建控制台应用 Windows控制台程序…...

【Python语言速回顾】——数据可视化基础

目录 引入 一、Matplotlib模块&#xff08;常用&#xff09; 1、绘图流程&常用图 ​编辑 2、绘制子图&添加标注 ​编辑 3、面向对象画图 4、Pylab模块应用 二、Seaborn模块&#xff08;常用&#xff09; 1、常用图 2、代码示例 ​编辑 ​编辑 ​编辑 ​…...

java实现pdf文件添加水印,下载到浏览器

java实现pdf文件添加水印&#xff0c;下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …...

代码随想录算法训练营第四十一天丨 动态规划part04

01背包理论基础 见连接&#xff1a;代码随想录 416. 分割等和子集 思路 01背包问题 背包问题&#xff0c;大家都知道&#xff0c;有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)

漏洞概述 漏洞名称&#xff1a;Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号&#xff1a;CVE-2023-25194 CVSS评分&#xff1a;8.8 影响版本&#xff1a;Apache Kafka 2.3.0 - 3.3.2 修复版本&#xff1a;≥ 3.4.0 漏洞类型&#xff1a;反序列化导致的远程代…...