【SpringCloud——Sentinel】

news2024/11/25 20:35:11

一、什么是雪崩?

微服务调用链路中的某个服务发生故障,引起整个链路中的所有微服务都不可用,这就是雪崩。

 二、解决雪崩问题的常见措施

1、超时处理

设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待。

 弊端:假设等待时间为1s,但是每秒钟传递过来的请求为2个,迟早有一天,线程数量也会填满整个tomcat服务器。

2、舱壁模式

限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。

3、熔断降级

由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。

 假设上层服务调用了三次下层服务,其中两次都调用失败,那么此时的异常比例就为百分之66,此时就熔断对下层服务的访问,一切访问下层服务的请求都将被立即拦截。

4、流量控制

限制业务访问的QPS,避免服务因流量的突增而故障。主要针对高并发场景下进行流量控制,假设某服务处理请求的效率为每秒2个,当某一时刻大量的请求涌入时,就会控制请求的传递效率,保证服务的正常运行,否则该服务将被大量请求直接拖垮。

 5、总结

 三、Sentinel与SpringCloud整合

1、引入依赖

        <!--引入sentinel依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

2、配置连接

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 #sentinel控制台地址

四、限流规则

1、如何设置流量控制?

在学习如何设置流量控制前,我们先了解什么是簇点链路:

簇点链路就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源。

 简单点来说,就是Controller层当中的各个请求接口。

 下面我们来看看如何设置单个接口的流量控制:

 

 2、流量控制模式

在添加限流规则时,点击高级选项,可以选择三种流控模式:

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
  • 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流

①、关联模式

使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是有限支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。

模拟案例:

代码:

    @GetMapping("/query")
    public String queryOrder(){
        return "查询订单成功";
    }

    @GetMapping("/update")
    public String updateOrder(){
        return "更新订单成功";
    }

sentinel控制台:

对谁进行限流就 设置谁的流量控制!

 这个配置的意思就是说,当update的QPS触发阈值时,此时就限制对query的访问,即拦截。这么做的目的就在于优先执行订单修改服务。

 此处update和query就针对数据库的锁产生了竞争,即读的时候不可以修改,修改的时候也不可以读,因此,则设置优先执行写操作,而限制读操作的进行。

②、链路模式

       链路模式常常用于对资源的一种分配,比如有一个服务A同时被服务B和服务C调用,服务A处理请求的能力有限(每秒处理6条),并不能同时处理B和C同一时刻传递过来的请求(每秒各4条,共8条),此时我们就需要对B或C的部分请求进行拦截了,具体拦截谁的,就看谁的优先级低,假设B是订单支付,C是订单查询,支付的优先级是高于查询的,因此我们就会针对服务A的请求来源服务C进行限流。

模拟案例:

代码:

    @SentinelResource("goods")
    public void queryGoods(){
        System.err.println("查询商品");
    }
    @GetMapping("/save")
    public String saveOrder(){
        //查询商品
        orderService.queryGoods();
        //新增订单
        System.out.println("新增订单");
        return "新增订单成功";
    }
    @GetMapping("/query")
    public String queryOrder(){
        //查询商品
        orderService.queryGoods();
        //查询订单
        System.out.println("查询订单");
        return "查询订单成功";
    }

Sentinel控制台:

针对goods服务设置链路流控:

 

 设置完成后,创建订单服务和查询服务同时进行,各自每秒访问4次,就可以发现,查询服务每秒只有两条请求成功了,其余两条则会被sentinel拦截。

注意:创建订单服务和查询订单服务并没有竞争关系,链路模式是出于对代码可靠性的一种保护措施,防止服务压力过大导致的宕机。

3、流控效果

流控效果是指请求达到流控阈值时应该采取的措施,包括三种:

  • 快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
  • warm up:预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
  • 排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长

①、warm up

warm up也叫预热模式,是应对服务冷启动的一种方案。

请求阈值初始值是 threshold (最大阈值)/ coldFactor,持续指定时长后,逐渐提高到threshold值。而coldFactor的默认值是3.

例如,我设置QPS的threshold为10,预热时间为5秒,那么初始阈值就是 10 / 3 ,也就是3,然后在5秒后逐渐增长到10.

 

 假设我们每秒的访问量为10,在起初的1s内,会有3条请求响应成功,其余的都会被sentinel拦截了,在接下来的4s内,阈值会逐步增大,逐渐增大到10,在未增大到10时,部分请求仍然会被拦截。

②、排队等待

模拟案例:

给/order/{orderId}这个资源设置限流,最大QPS为10,利用排队的流控效果,超时时长设置为5s

 计算:

我们假设每秒有15个请求到达该服务,此处的单机阈值为10,即可以假设每个请求的处理时间为100ms,则每秒钟就会有5个请求放到队列当中,当到第十秒时,队列当中的请求就会放满,此时,再来的请求就有可能会被直接拦截。

③、总结 

 4、热点参数限流

之前的限流是统计访问某个资源的所有请求,判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。

 热点参数限流即限制对热点参数的访问,限制其控制在一个特定值范围内,防止大量相同请求访问同一资源。

五、隔离和降级

1、FeignClient整合Sentinel

SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合Feign和Sentinel。

①、修改OrderService的application.yml文件,开启Feign的Sentinel功能

feign:
  httpclient:
    enabled: true #支持httpClient的开关
    max-connections: 200 #最大连接数
    max-connections-per-route: 50 #单个请求路径的最大连接数
  sentinel:
    enabled: true #开启feign对sentinel的支持

②、在feing-api项目中定义类,实现FallbackFactory

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {

    @Override
    public UserClient create(Throwable throwable) {
        return new UserClient() {
            @Override
            public User findById(Long id) {
                log.error("查询用户异常",throwable);
                return new User();
            }
        };
    }
}

③、在feing-api项目中的DefaultFeignConfiguration类中将UserClientFallbackFactory注册为一个Bean

    @Bean
    public UserClientFallbackFactory userClientFallbackFactory(){
        return new UserClientFallbackFactory();
    }

④、在feing-api项目中的UserClient接口中使用UserClientFallbackFactory

@FeignClient(value = "userservice",
        configuration = DefaultFeignConfiguration.class,
        fallbackFactory = UserClientFallbackFactory.class)//只针对userservice服务有效 全局有效在启动类的注解当中配置即可
public interface UserClient {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

2、线程隔离(舱壁模式)

线程隔离有两种方式:

  • 线程池隔离
  • 信号量隔离(Sentinel默认方式)

 

 

 在添加限流规则时,可以选择两种阈值类型:

 

3、熔断降级

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

 断路器熔断策略有三种:慢调用、异常比例、异常数。

        if (id == 1){
            Thread.sleep(60);
        }else if (id == 2){
            throw new RuntimeException("故意出错,触发熔断");
        }

①、慢调用

        业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。

 解读:RT超过500ms的调用是慢调用,统计最近10000ms内的请求,如果请求量超过10次,并且慢调用比例不低于0.5,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。

②、异常比例或异常数

异常比例或异常数:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。

 

 解读:统计最近1000ms内的请求,如果请求量超过10次,并且异常比例不低于0.5,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。

六、授权规则和规则持久化

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

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

 案例:限定只允许从网关来的请求访问order-service,那么流控应用中就填写网关的名称。

①、网关过滤器添加请求头

        - AddRequestHeader=Origin,gateway

②、Sentinel是通过RequestOriginParser这个接口的parseOrigin来获取请求的来源的。

实现这个接口,判断请求来源。

@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        //获取请求头
        String origin = httpServletRequest.getHeader("Origin");
        //判断请求头
        if (StringUtils.isEmpty(origin)){
            origin =  "black";// 黑名单
        }
        return origin;
    }
}

③、Sentinel控制台配置授权

 ④、测试

http://localhost:10010/order/101?authorization=admin
http://localhost:8010/order/101

 

1、如何自定义异常结果

默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。如果要自定义异常时的返回结果,需要实现BlockExceptionHandler接口。

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = "未知异常";
        int status = 429;

        if (e instanceof FlowException) {
            msg = "请求被限流了";
        } else if (e instanceof ParamFlowException) {
            msg = "请求被热点参数限流";
        } else if (e instanceof DegradeException) {
            msg = "请求被降级了";
        } else if (e instanceof AuthorityException) {
            msg = "没有权限访问";
            status = 401;
        }

        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
    }
}

2、规则持久化

Sentinel管理配置的三种模式:

  • 原始模式:配置信息保存在内存,服务重启则失效。
  • pull模式:保存在本地文件或者数据库,定时去读取,时效性比较差。
  • push模式:保存在nacos,监听变更实时更新。

 push模式管理配置

①、引入依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

②、修改order-service服务,使其监听Nacos配置中心

spring:
  application:
    name: orderservice
  profiles:
    active: dev
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 #sentinel控制台地址
      web-context-unify: false #关闭context整合
      datasource:
        flow:
          nacos:
            serverAddr: localhost:80
            dataId: orderservice-flow-rules
            groupId: SENTINEL_GROUP
            ruleType: FLOW #还可以是:degrade、authority、param-flow

③、修改Sentinel-dashboard源码,修改前端页面

详细步骤参考网上文档。

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

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

相关文章

vue 3 第三十三章:自定义 hooks

文章目录 1. vue 2 中mixins1.1. mixins 的缺点&#xff1a; 2. 自定义 hooks2.1. 创建自定义Hook2.2. 在组件中使用自定义Hook 2. 总结 1. vue 2 中mixins 在Vue.js 2.x版本中&#xff0c; mixin 被广泛用于将组件的逻辑、计算属性和方法复用到其他组件中。然而&#xff0c;使…

华为OD机试真题 Java 实现【明明的随机数】【2023Q1 100分】,附详细解题思路

一、题目描述 明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字&#xff0c;即相同的数字只保留一个&#xff0c;把其余相同的数去掉&#xff0c;然后再把这些数从小到大排序&#xff0c;按照排好的顺序输出。 数据范围&#xff1a; 1≤n≤1000 &#xff0c;输入…

springboot+vue游戏项目销售发行系统设计与实现

本游戏销售平台管理员功能有个人中心&#xff0c;用户管理&#xff0c;厂商管理&#xff0c;游戏类型管理&#xff0c;游戏信息管理&#xff0c;众筹项目管理&#xff0c;项目投资管理&#xff0c;论坛管理&#xff0c;管理员管理&#xff0c;系统管理等。厂商发布游戏&#xf…

我在公司彻夜加班,老板居然做出这种事.....

讲道理&#xff0c;我的学历远达不到BAT等名企大厂的要求&#xff0c;去不了好公司我认了&#xff0c;大专毕业的我在找工作的时候发现留给自己的机会并不多&#xff0c;最后去了一家不知名的小公司。入职后才发现这家公司其实就是个外包公司&#xff0c;里面的业务部门和制度相…

使用Mybatis接口开发

文章目录 目录 前言 公司项目用到了mybatis开发接口,虽然很简单,但是mybatis不是特别熟悉,这里学习一下 一、Mybatis接口绑定的两种方式 1.接口绑定实现方式 就是在接口的方法上加上Select,updateInsertDelete等注解 select注解介绍: 简便,能快速去操作sql,它只需要在mapper…

AIGC浪潮来袭,奇点云“数智科技大会”洞见AI加速的数智未来

“进化&#xff0c;发生在每一个数字化场景。” 5月25日&#xff0c;以“数据进化论”为主题&#xff0c;由StartDT&#xff08;奇点云、GrowingIO&#xff09;主办的2023 StartDT Day数智科技大会在杭召开。企业客户、行业专家、技术专家与数万位参会伙伴相聚云上&#xff0c;…

【Linux】shell脚本教程

目录 一、shell历史 二、执行脚本 三、基本语法 3.1变量 3.1.1变量的分类 3.1.2删除变量 3.2文件名代换&#xff08;Globbing&#xff09; 3.3命令代换 3.4算术代换 3.5转义字符 3.6单引号 3.7双引号 四、Shell脚本语法 4.1条件测试 4.2分支 4.2.1if/then/elif…

【SLAM】Kimera-Multi (IEEE-TRO2022 年最佳论文傅京孙)

Kimera-Multi: Robust, Distributed, Dense Metric-Semantic SLAM for Multi-Robot Systems 0 摘要1. 引言2. RELATED WORK3. SYSTEM OVERVIEW4. DISTRIBUTED LOOP CLOSURE DETECTION[4.X Kimera-Multi相关补充](https://github.com/DEARsunshine/Kimera)5. EXPERIMENTS6. CONC…

推箱子-第14届蓝桥杯国赛Scratch真题初中级组第3题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第145讲。 推箱子&#xff0c;本题是2023年5月28日上午举行的第14届蓝桥杯国赛Scratch图形化编程初中级组真题第3题&am…

苹果iOS证书制作教程

众所周知&#xff0c;如果你需要上架苹果APP就必须要苹果iOS证书进行APP签名&#xff0c;否则苹果手机将无法安装你开发的APP&#xff0c;废话不多说&#xff0c;直接上教程。 第一步&#xff0c;注册账号 准备appleid必须开通双重认证&#xff0c;如果注册个人开发者直接下载d…

深度学习基础知识-tf.keras实例: 加州房价预测

参考书籍&#xff1a;《Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 2nd Edition (Aurelien Geron [Gron, Aurlien])》 代码有修改&#xff0c;已测通。 简单顺序结构 这次得数据集比之前得简单&#xff0c;只包含数字型特征&#xff0c;没有ocean…

leetcode98. 验证二叉搜索树(java)

验证二叉搜索树 leetcode98. 验证二叉搜索树题目描述 递归法解题思路代码演示 中序遍历解法解题思路代码演示 二叉树专题 leetcode98. 验证二叉搜索树 leetcode 98.验证二叉搜索树 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/…

Linux开发中的辅助工具

文章目录 前言一、add2line二、strip三、ar四、nm五、objdump六、size七、strings总结 前言 本篇文章我们来介绍一些Linux开发中的辅助工具&#xff0c;有了这些辅助工具将会让我们的开发变的更加轻松。 一、add2line addr2line是一个GNU调试工具&#xff0c;用于将程序计数…

priority_queue的模拟实现和仿函数

priority_queue模拟 首先查看源代码&#xff0c;源代码就在queue剩下的部分中 push_heap是STL库中的堆算法&#xff0c;STL库中包装有支持堆的算法&#xff0c;在algorithm.h中&#xff1a; 只要不断用堆的形式插入数据&#xff0c;就会形成堆。 priority_queue模拟——初版 pr…

自定义组件中,使用onLoad,onShow生命周期失效问题

的解决方法 自定义组件中&#xff0c;使用onLoad,onShow生命周期失效问题 自定义组件中&#xff0c;使用onLoad,onShow生命周期失效问题 官方文档可查阅到&#xff1a; 页面生命周期仅在page中的vue页面有效&#xff0c;而单独封装的组件中【页面周期无效】&#xff0c;但是Vu…

Pytorch入门(四)使用VGG16网络训练CIFAR10数据集

本文使用PytorchVGG16官方CIFAR10数据集完成图像分类。识别效果如下&#xff1a; 文章目录 一、VGG16 神经网络结构二、VGG16 模型训练三、预测CIFAR10中的是个类别 一、VGG16 神经网络结构 VGG&#xff0c;又叫VGG-16&#xff0c;顾名思义就是有16层&#xff0c;包括13个卷…

地震勘探基础(十)之地震速度关系

地震速度 地震勘探中引入了多种速度的概念&#xff0c;如下图所示。 层速度、平均速度和均方根速度之间的关系 层速度指的是某一套地层垂向上&#xff0c;由于地质条件相对稳定&#xff0c;地层顶底厚度比上地震波的传播时间为层速度&#xff0c;用 v n v_n vn​ 表示。 如下…

一文看懂软件架构4+1视图

目录 一、概述 二、各视图详解 1. 场景视图 2. 逻辑视图 3. 开发视图 4. 处理视图 5. 物理视图 葵花宝典&#xff1a;一看就懂的理解方式 一、概述 41视图包括&#xff1a; 场景视图&#xff08;也叫用例视图&#xff09;&#xff1a;黑盒视图。从外部视角&#xff…

chatgpt赋能python:Python如何分段数据的平均数

Python如何分段数据的平均数 Python是一门极其流行的编程语言&#xff0c;广泛应用于数据分析与科学计算领域。在数据分析中&#xff0c;计算各个数据段的平均数是一项常见的任务。本文将介绍如何使用Python分段计算数据的平均数&#xff0c;以及如何优化这一过程以使速度更快…

Linux中的lrzsz

一、介绍 lrzsz是一款在Linux里可代替ftp上传和下载的程序,也就是一款软件。它是开发者常用的一款工具,这个工具用于windows机器和远端的Linux机器通过XShell传输文件。 二、lrzsz的安装 在安装之前,我们可以使用下述命令先查看yum仓库中是否存在我们要安装的软件: yum…