SpringCloud源码探析(九)- Sentinel概念及使用

1.概述

在微服务的依赖调用中,若被调用方出现故障,出于自我保护的目的,调用方会主动停止调用,并根据业务需要进行对应处理,这种方式叫做熔断,是微服务的一种保护方式。为了保证服务的高可用性,springcloud中有专门的流量管控组件,负责熔断、限流和降级。springcloud中较为知名的熔断器有Hystrix和Sentinel,本文将分析Sentinel的优势及其使用。

2.Sentinel使用

在微服务调用中,可能会因为调用链中的一个服务发生故障,导致整个链路都无法访问的情况,这种现象叫雪崩。解决雪崩的常用方法有:

  • 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等等;
  • 舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离;
  • 熔断降级:由断路器统计业务执行的异常比例,如果超过阈值则会熔断该业务,拦截访问该业务的一起请求;
  • 流量控制:限制业务访问的QPS,避免因流量的突增而故障。

2.1 Hystrix和Sentinel对比

对比项SentinelHystrix
隔离策略信号量隔离线程池/信号量隔离
熔断降级策略基于慢调用比例或异常比例基于失败比例
实时指标实现滑动窗口滑动窗口(基于RxJAVA)
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件的形式
基于注解的支持支持支持
限流基于QPS,支持基于调用关系的限流有限的支持
流量整形支持慢启动,匀速排队模式不支持
系统自适应保护支持不支持
控制台开箱即用、可配置规则、查看秒级监控、机器发现等不完善
常见框架的适配Servlet、Spring Cloud、Dubbo、gRPC等Servlet、Spring Cloud Netflix

Sentinel相对于Hystrix有更完善的限流机制,能够实现动态限流。由于Netflix已经宣布对Hystrix停止更新,意味着Hystrix不会再有新的功能迭代,而Sentinel是由阿里巴巴开源的一款微服务流量控制组件,具有丰富的应用场景(承接了阿里巴巴近10年的双十一大促流量的核心场景)、完备的实时监控、广泛的开源生态、完善的SPI扩展点。

2.2 Sentinel使用

2.2.1 Sentinel安装及使用

本文主要演示单机版本下sentinel的安装及使用,主要步骤如下:
(1)下载安装包:从官网下载sentinel-dashboard安装包;
(2)启动sentinel:通过java -jar命令启动sentinel,可以通过在启动命令中增加参数来调整,比如 -Dserver.port=8888,因为sentinel是基于springboot开发的JAVA项目;默认情况下,sentinel-dashboard以8080端口启动;
(3)验证是否启动成功:通过访问http://127.0.0.1:8080,若出现以下页面,则启动成功。
在这里插入图片描述
注意事项:1.6版本以上才有这个登陆界面,默认用户名和密码均为sentinel,如果要修改用户名和密码,可以通过修改启动时配置:

-Dsentinel.dashboard.auth.username = sentinel://指定登录名称为sentinel;
-Dsentinel.dashboard.auth.password=123456://指定控制台的登录密码为:123456,默认值为sentinel
-Dserver.servlet.session.timeout = 7200://指定Spring Boot 服务端 session的过期时间,如7200表示7200秒,30m表示30分钟,默认为30分钟

2.2.2 SpringBoot整合Sentinel

1.引入pom文件

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

2.添加配置文件
指定sentinel的安装地址和IP,

spring.cloud.sentinel.transport.dashboard=http://localhost:8080

3.添加restful API

    @GetMapping("/test")public ResultBean test() {return ResultBean.success("请求sentinel成功");}

启动服务,请求接口后刷新Sentinel客户端,会出现如下界面:
在这里插入图片描述

2.2.3 Sentinel流控模式

Sentinel的流控模式,主要有以下三种:

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认模式;这个比较容易理解,服务A触发阈值,就对服务A进行限流;
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流;例如有服务A和服务B两个资源,服务A触发阈值,却对服务B进行资源限流;
  • 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流;例如有服务A、B、C,服务A、B均要访问服务C,只统计从服务A到C的请求,超过阈值,对A限流。

在这里插入图片描述
流控效果是指请求达到流控阈值时应采取的措施,包括三种:

  • 快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException一次,是默认的处理方式;
  • warm up(预热模式):对超出阈值的请求同样是拒绝并抛出异常,但这种模式阈值会动态变化;预热模式是应对冷启动的一种方案,请求阈值初始值是threshold/coldFactor,持续指定时长后,逐渐提高到threshold,而coldFactor的默认值是3;例如:设置QPS的threshold为10,预热时间为10s,那么初始阈值就是10/3,也就是3,然后在5s后逐渐增长到10;
  • 排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长。排队等待让所有请求进入到一个队列中,然后按照阈值允许的时间间隔依次执行,后来的请求必须等前面的执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。例如:QPS=5,意味着每200ms处理一个队列中的请求;timeout=2000,意味着预期等待超过2000ms的请求会被拒绝并抛出异常。

2.2.3 OpenFeign整合Sentinel

这里演示订单服务order-service调用用户服务user-service查询用户信息,在order-service服务中添加Feign接口,并添加失败调用逻辑类FallbackFactory,里面是调用order-service接口异常所返回的逻辑。
OpenFeign整合Sentinel的核心步骤如下:
1.在配置文件中添加配置

 #配置sentinel注册地址spring.cloud.sentinel.transport.dashboard=http://127.0.0.1:8080#开启Feign的sentinel功能feign.sentinel.enabled=true

2.实现FallbackFactory

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserFeign> {public UserFeign create(Throwable throwable) {return new UserFeign() {public String getUserById() {return "查询失败,用户不存在";}};}
}

3.将UserClientFallbackFactory注册为Bean

@Configuration
public class DefaultFeignConfiguration {@Beanpublic UserClientFallbackFactory userClientFallbackFactory() {return new UserClientFallbackFactory();}
}

4.在feign接口中配置UserClientFallbackFactory

@Component
@FeignClient(name = "user-service",fallbackFactory = UserClientFallbackFactory.class)
public interface UserFeign {@GetMapping("/user/findOrderByUserId")String getUserById();}

通过请求订单服务中的/order/feign接口,内部会调用user-service中/user/findOrderByUserId接口,完整链路如下图所示,此时就可以对user-service中/user/findOrderByUserId接口进行限流规则配置。
在这里插入图片描述

2.2.4 利用Sentinel实现线程隔离与降级熔断

1.线程隔离
限流可以尽量避免因高并发而引起的服务故障,但故障还是会因为其它原因而故障。需要将这些故障控制在一定范围,避免雪崩,就要靠现场隔离(舱壁模式)和熔断降级手段了。不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护。线程池隔离主要有两种方式:

1.线程池隔离:服务A请求服务B,在服务A开辟一个线程池(含指定数量线程),这个线程池专门负责请求服务B,该线程池隔离了服务A与其它服务的交互(只针对B服务),即使服务B出现故障,也能保证服务A不被影响,保证了服务A的独立性和高可用性;
2.信号量隔离:信号量的资源隔离,仅限制对某个资源调用的并发数,而不是显示地去创建线程池,效果更好。但缺点是无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。

线程池隔离与信号量隔离对比:

对比项线程池隔离信号量隔离
优点支持主动超时,支持异步调用轻量级,无额外开销
缺点增加线程额外开销不支持主动超时,不支持异步调用
适用场景适用于高频调用场景、高扇出(横向调用服务多)低扇出(横向调用服务少)

2.熔断降级
熔断降级是解决雪崩问题的重要手段,其核心思想是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务(拦截一切进入该服务的请求);当服务恢复时,断路器会放行访问该服务的请求。

断路器熔断策略主要有三种:慢调用、异常比例、异常数。
慢调用:业务的响应时长(RT)大于指定时长的请求就认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。
在这里插入图片描述

上述配置解读:RT超过500ms的调用就是慢调用,统计最近10s内的请求,如果请求量超过10次,并且慢调用比例不低于0.5,则触发熔断,熔断时长为5s,然后进入half-open状态,放行一次请求做测试,通过才继续放行请求进入服务。
在这里插入图片描述

异常比例:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。上述配置在1s内最小请求数为5,若异常比例超过0.2,则需要熔断,熔断时长为5s。
在这里插入图片描述
异常数量:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常超过指定异常数,则触发熔断。
上述配置解读:统计最近1s内的请求,如果请求量超过10次,并且异常数超过2次,则触发熔断,熔断时长为5s,然后进入half-open状态,放行一次请求做测试,通过才继续放行请求进入服务。

2.2.5 授权规则

授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。

白名单:来源(origin)在白名单内的调用者允许访问;
黑名单:来源(origin)在黑名单内的调用者不允许访问。

规则配置界面如下:
在这里插入图片描述
这里以白名单功能为例演示(从网关gateway服务访问的请求允许放行,从浏览器或其它服务访问则被拒绝),具体操作如下:
1.新增授权规则配置
在这里插入图片描述
资源名指的是所访问资源的请求路径,流控应用指请求头中所携带的约束字段,当从网关gateway服务请求到order-service中的/order/feign资源时,携带值为gateway的请求头,order-service获取访问资源的请求头,解析是否存在关键值gateway,存在则允许访问。
2.网关服务添加请求头

spring:cloud:gateway:routes:- id: order-serviceuri: lb://order-servicepredicates:- Path=/order/**filters:- AddRequestHeader=origin,gateway

在配置文件中添加filers配置,添加关键字为origin,值为gateway的配置。

3.在order-service中解析请求头

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;@Slf4j
@Component
public class RequestParse implements RequestOriginParser {public String parseOrigin(HttpServletRequest httpServletRequest) {String origin = httpServletRequest.getHeader("origin");if (StringUtils.isEmpty(origin) || !origin.equals("gateway")) {origin = "blank";}log.info("origin:{}", origin);return origin;}
}

在order-service服务中定义类RequestParse实现sentinel中的RequestOriginParser接口(通过该接口获取请求来源),解析请求头中是否携带key为origin,值为gateway的字段,存在则返回,不存在则赋值为blank返回,并注册为Bean。

4.自定义异常返回类(可选)

在order-service中自定义异常类实现sentinel的BlockException,可返回自定义异常。BlockException包含很多个子类,分别对应不同的场景:

异常说明
FlowException限流异常
ParamFlowException热点参数限流的异常
DegradeException降级异常
AuthorityException授权规则异常
SystemBlockException系统规则异常

自定义异常类如下:

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @Author: Marinc* @CreateTime: 2023-08-09  22:53* @Description: TODO* @Version: 1.0*/
@Component
public class ExceptionHandler implements BlockExceptionHandler {public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {String msg = "默认未知异常";Integer code = 1001;if (e instanceof FlowException) {msg = "限流异常";code = 1002;} else if (e instanceof ParamFlowException) {msg = "热点限流异常";code = 1003;} else if (e instanceof DegradeException) {msg = "降级异常";code = 1004;} else if (e instanceof AuthorityException) {msg = "授权异常";code = 1005;} else {msg = "系统异常";code = 1009;}httpServletResponse.setStatus(code);httpServletResponse.setContentType("application/json;charset=utf-8");httpServletResponse.getWriter().print("{"+"message:" + msg + ",code:" + code+"}");}
}

验证结果,从经过网关gateway访问order-service服务的请求结果为:
在这里插入图片描述
直接从访问order-service服务的请求结果为:
在这里插入图片描述

2.2.5 Sentinel规则管理模式

Sentinel的控制台规则管理有三种模式:

1.原始模式:将规则保存在内存,重启服务会丢失;
2.pull模式:控制台将配置的规则推送到Sentinel客户端,而客户端会将配置规则保存至本地文件或数据库中,以后会定时去本地文件或数据库中查询,更新本地规则;
3.push模式:控制台将配置规则推送到远程配置中心,例如nacos,sentinel客户端监听nacos,获取配置变更的推送消息,完成本地配置更新。

这三种管理模式可根据场景进行选择使用,pull模式和push模式在下文中进行演示。

3.小结

1.sentinel相对于Hystrix,支持更多流控规则的制定,适配更多外部框架,功能更强大;
2.sentinel可以更加灵活地配置熔断时长,拥有更多灵活的配置策略;
3.sentinel可以将配置规则保存至内存、文件和注册中心,可以根据场景进行选择,更加灵活。

4.参考文献

1.https://www.bilibili.com/video/BV1LQ4y127n4
2.https://juejin.cn/post/6983824085306310692
3.https://sentinelguard.io/zh-cn/

5.附录

1.https://gitee.com/Marinc/nacos.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/32102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

即然利用反射机制可以破坏单例模式,有什么方法避免呢?

私有构造方法中添加防止多次实例化的逻辑&#xff1a;在单例类的私有构造方法中&#xff0c;可以添加逻辑来检查是否已经存在实例&#xff0c;如果存在则抛出异常或返回已有的实例。这样即使通过反射创建了新的实例&#xff0c;也能在构造方法中进行拦截。 使用枚举实现单例&a…

rknn3588如何查看npu使用情况

cat /sys/kernel/debug/rknpu/load

choices参数的使用、MTV和MVC的概念、对多的三种创建方式、Ajax技术

一、choices参数的使用 choices它是ORM中常用字段中的参数choices的作用&#xff1a;类似于一些字段&#xff1a;性别、学历、客户来源、是否上学、是否结婚等字段# 针对于一些字段它的情况能够被列举完&#xff0c;像这样的字段&#xff0c;我们在表中存储的时候一般使用choi…

windows环境下编译OpenJDK12

环境&#xff1a;Windows11 目录&#xff1a; 1、下载OpenJDK12源码 下载地址&#xff1a; https://hg.openjdk.org/jdk/jdk12 点击zip下载到本地。 解压到本地。 Tip&#xff1a;注意本地路径中最好不要包含中文或空格。 2、阅读一遍doc/building.html 如果只是想构建J…

白帽黑帽与linux安全操作

目录 白帽黑帽 Linux安全 白帽黑帽 白帽&#xff08;White Hat&#xff09;和黑帽&#xff08;Black Hat&#xff09;通常用于描述计算机安全领域中的两种不同角色。白帽黑客通常被认为是合法的安全专家&#xff0c;他们通过合法途径寻找和修复安全漏洞&#xff0c;帮助企业和…

Linux/centos上如何配置管理samba服务器?

Linux/centos上如何配置管理samba服务器&#xff1f; 1 samba服务相关知识1.1 SMB协议1.2 samba工作原理1.2.1 相关进程1.2.2 samba工作流程1.2.3 samba功能 2 samba服务器安装2.1 利用光驱安装2.2 利用光盘映射文件 3 启动与停止samba服务4 配置samba服务器4.1 samba主配置文件…

解读百威亚太2023上半年财报:啤酒大年百威如何重塑高端化之路?

随着消费者的需求提升&#xff0c;啤酒行业向高端化发展&#xff0c;其中知名度较高的百威亚太、华润啤酒、青岛啤酒、燕京啤酒、嘉士伯等品牌在高端市场持续鏖战&#xff0c;实际成果如何也可以从业绩一探究竟。 以百威亚太为例。8月3日&#xff0c;百威亚太发布2023年上半年…

记录一次electron打包提示文件找不到的解决方法

没有配置files选项 files的作用是配置打包到应用程序的构建资源 就是说如果你想使用项目那个目录下的文件 就得通过files配置一下不然就会报错 json文件或者yml文件会报的错 格式是这样的 "files": ["dist-electron", "dist"],electron打包配…

React配置代理服务器的5种方法

五种方法的介绍 以下是五种在React项目中配置代理服务器的方法的使用场景和优缺点&#xff1a; 1. 使用 http-proxy-middleware 中间件&#xff1a; 使用场景&#xff1a;适用于大多数React项目&#xff0c;简单易用。优点&#xff1a;配置简单&#xff0c;易于理解和维护。…

【C++学习】STL容器——list

目录 一、list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list 迭代器失效 二、list的模拟实现 2.1 模拟实现list 三、list和vector的对比…

HTTPS、TLS加密传输

HTTPS、TLS加密传输 HTTPS、TLS加密传输1、HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;2、TLS HTTPS、TLS加密传输 1、HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09; HTTPS&#xff08;HyperText Transfer Protocol Secure&#x…

Ozone命令行接口详解

命令行接口简介 Ozone Shell是命令行与Ozone交互的主要界面&#xff0c;底层用的是Java。 有些功能只能通过Ozone Shell进行操作&#xff1a; 创建带有限额限制的Volume管理内部ACLs&#xff08;访问控制列表&#xff09;创建带有加密密钥的存储桶 大部分操作除了Shell操作…

【算法挨揍日记】day01——双指针算法_移动零、 复写零

283.移动零 283. 移动零https://leetcode.cn/problems/move-zeroes/ 题目&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 …

【BASH】回顾与知识点梳理(十二)

【BASH】回顾与知识点梳理 十二 十二. Linux 文件与目录管理12.1 目录与路径相对路径与绝对路径相对路径的用途绝对路径的用途 12.2 目录的相关操作cd (change directory, 变换目录)pwd (Print Working Directory, 显示目前所在的目录)mkdir (make directory, 建立新目录)rmdir…

生信豆芽菜-火山图绘制使用说明

网站&#xff1a;http://www.sxdyc.com/visualsVolcano 一、火山图简介 火山图是散点图的一种&#xff0c;它将统计测试中的统计显著性量度&#xff08;如p value&#xff09;和变化幅度&#xff08;logFC&#xff09;相结合&#xff0c;能够快速直观地识别那些变化幅度较大且具…

13个Python最佳编程技巧,越早知道越好

每天我们都会面临许多需要高级编码的编程挑战。你不能用简单的 Python 基本语法来解决这些问题。在本文中&#xff0c;我将分享 13 个高级 Python 脚本&#xff0c;它们可以成为你项目中的便捷工具。如果你目前还用不到这些脚本&#xff0c;你可以先添加收藏&#xff0c;以备留…

24大连交通大学813软件工程考研习题

1.等价分类法相关概念。 &#xff08;1&#xff09;等价分类法的基本思想是什么&#xff1f; 根据程序的输入特性&#xff0c;将程序的定义域划分为有限个等价区段 —“等价类”&#xff0c;从等价类中选择出的用例具有“代表性”&#xff0c;即测试某个等价类的代表值就等价…

springMVC 程序开发

目录 一. 认识 springMVC spring&#xff0c;springBoot&#xff0c;springMVC的关系 二. springMVC 的连接和获取参数 1. 注解分析&#xff08;不带参数&#xff09; 2. 获取参数 3. 获取对象参数 4. 重命名功能 5. 获取 JSON 对象 6. 通过 path 文件路径来传递参数…

新版Android Studio模拟器浮动

&#xff08;水一篇&#xff0c;但其实很多入门同学不知道&#xff09; 安装新版Andorid Studio后会发现模拟器是内嵌在AS中的&#xff0c;如何让她浮动

[C++项目] Boost文档 站内搜索引擎(4): 搜索的相关接口的实现、线程安全的单例index接口、cppjieba分词库的使用、综合调试...

有关Boost文档搜索引擎的项目的前三篇文章, 已经分别介绍分析了: 项目背景: &#x1fae6;[C项目] Boost文档 站内搜索引擎(1): 项目背景介绍、相关技术栈、相关概念介绍…文档解析、处理模块parser的实现: &#x1fae6;[C项目] Boost文档 站内搜索引擎(2): 文档文本解析模块…