微服务保护

news2025/2/25 14:32:48

一、初识Sentinel

1. 雪崩问题及解决方案

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

解决雪崩问题的常见方式有四种:

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

(2)舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。

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

(4)流量控制:限制业务访问的QPS,避免服务因流量的突增而故障。

2. 服务保护技术对比

3. Sentinel介绍和安装

Sentinel是阿里巴巴开源的一款微服务流量控制组件。

官网地址:https://sentinelguard.io/zh-cn/index.html

3.1 安装Sentinel控制台

sentinel官方提供了UI控制台,方便我们对系统做限流设置。

大家可以在GitHub下载。课前资料提供了下载好的jar包:

(1)将其拷贝到一个你能记住的非中文目录,然后运行命令:

java -jar sentinel-dashboard-1.8.1.jar

然后访问:localhost:8080 即可看到控制台页面,默认的账户和密码都是sentinel

 

如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:

举例说明

java -jar sentinel-dashboard-1.8.1.jar -Dserver.port=8090

4. 微服务整合Sentinel

我们在order-service中整合Sentinel,并且连接Sentinel的控制台,步骤如下:

(1)引入sentinel依赖:

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

(2)配置控制台地址:

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

(3)访问微服务的任意端点,触发sentinel监控

二、流量控制

1. 簇点链路

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

流控、熔断等都是针对簇点链路中的资源来设置的,因此我们可以点击对应资源后面的按钮来设置规则:

2.快速入门

点击资源/order/{orderId}后面的流控按钮,就可以弹出表单。表单中可以添加流控规则,如下图所示:

其含义是限制 /order/{orderId} 这个资源的单机 QPS 为1,即每秒只允许1次请求,超出的请求会被拦截并报错。

2. 流控模式

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

(1)直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式

(2)关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流

(3)链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流

2.1 流控模式-关联

关联模式:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流

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

当/write资源访问量触发阈值时,就会对/read资源限流,避免影响/write资源。 

满足下面条件可以使用关联模式:

(1)两个有竞争关系的资源

(2)一个优先级较高,一个优先级较低

2.2 流控模式-链路

链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。

例如有两条请求链路:

(1)/test1          ->         /common

(2)/test2          ->         /common

如果只希望统计从/test2进入到/common的请求,则可以这样配置:

(1)Sentinel 默认只标记 Controller 中的方法为资源,如果要标记其它方法,需要利用 @SentinelResource 注解,示例:

    @SentinelResource("goods")
    public void queryGoods(){
        System.err.println("查询商品");
    }

(2)Sentinel 默认会将 Controller 方法做 context 整合,导致链路模式的流控失效,需要修改 application.yml,添加配置:

spring:  
  cloud:    
    sentinel:
      transport:
        dashboard: localhost:8080 # sentinel控制台地址
      web-context-unify: false # 关闭context整合

3. 流控效果

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

(1)快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。

(2)warm up:预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。

(3)排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长

3.1 流控效果-warm up

warm up也叫预热模式,是应对服务冷启动的一种方案。请求阈值初始值是 threshold / coldFactor,持续指定时长后,逐渐提高到threshold值。而coldFactor的默认值是3.

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

3.2 流控效果-排队等待

当请求超过QPS阈值时,快速失败和warm up 会拒绝新的请求并抛出异常。而排队等待则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。

例如:QPS = 5,意味着每200ms处理一个队列中的请求;timeout = 2000,意味着预期等待超过2000ms的请求会被拒绝并抛出异常

4. 热点参数限流

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

配置示例:

代表的含义是:对hot这个资源的0号参数(第一个参数)做统计,每1秒相同参数值的请求数不能超过5 

在热点参数限流的高级选项中,可以对部分参数设置例外配置:

结合上一个配置,这里的含义是对0号的long类型参数限流,每1秒相同参数的QPS不能超过5,有两个例外:

(1)如果参数值是100,则每1秒允许的QPS为10

(2)如果参数值是101,则每1秒允许的QPS为15 

热点参数限流对默认的SpringMVC资源无效

三、隔离和降级

虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。

不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护。

1. FeignClient整合Sentinel

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

(1)修改OrderService的application.yml文件,开启Feign的Sentinel功能

feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持

(2)给FeignClient编写失败后的降级逻辑

1️⃣方式一:FallbackClass,无法对远程调用的异常做处理

2️⃣方式二:FallbackFactory,可以对远程调用的异常做处理,我们选择这种

步骤一:在feing-api项目中定义类,实现FallbackFactory:

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
    @Override
    public UserClient create(Throwable throwable) {
        // 创建UserClient接口实现类,实现其中的方法,编写失败降级的处理逻辑
        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", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {

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

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

线程隔离有两种方式实现:

(1)线程池隔离

(2)信号量隔离(Sentinel默认采用)

2.1 线程池隔离

(1)优点:

        1️⃣支持主动超时

        2️⃣支持异步调用

(2)缺点:

        线程的额外开销比较大

(3)场景:

        低扇出

2.2 信号量隔离

(1)优点:

        轻量级,无额外开销

(2)缺点:

        1️⃣不支持主动超时

        2️⃣不支持异步调用

(3)场景:

        1️⃣高频调用

        2️⃣高扇出

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

(1)QPS:就是每秒的请求数,在快速入门中已经演示过

(2) 线程数:是该资源能使用用的tomcat线程数的最大值。也就是通过限制线程数量,实现舱壁模式

3. 熔断降级

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

3.1 熔断策略-慢调用

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

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

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

3.2 熔断策略-异常比例、异常数

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

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

四、授权规则

1. 授权规则

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

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

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

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

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

public interface RequestOriginParser {
    /**
    *从请求request对象中获取origin(获取方式自定义)
    */
    String parseOrigin(HttpServletRequest var1);
}

例如,我们尝试从request中获取一个名为origin的请求头,作为origin的值:

@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        // 1.获取请求头
        String origin = request.getHeader("origin");
        // 2.非空判断
        if (StringUtils.isEmpty(origin)) {
            origin = "blank";
        }
        return origin;
    }
}

我们还需要在gateway服务中,利用网关的过滤器添加名为gateway的origin头:

spring:
  cloud:   
    gateway:     
      default-filters:       
        - AddRequestHeader=origin,gateway # 添加名为origin的请求头,值为gateway

给/order/{orderId} 配置授权规则:

2. 自定义异常结果

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

public interface BlockExceptionHandler {
     /**
     * 处理请求被限流、降级、授权拦截时抛出的异常:BlockException
     */
    void handle(HttpServletRequest var1, HttpServletResponse var2, BlockException var3) throws Exception;
}

而BlockException包含很多个子类,分别对应不同的场景:

我们在order-service中定义类,实现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 + "}");
    }
}

五、规则持久化

1. 规则管理模式

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

推送模式

说明

优点

缺点

原始模式

API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource),默认就是这种

简单,无任何依赖

不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境

Pull 模式

扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等

简单,无任何依赖;规则持久化

不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。

Push 模式

扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。

规则持久化;一致性;

引入第三方依赖

1.1 Sentinel的三种配置管理模式是什么?

(1)原始模式:保存在内存

(2)pull模式:保存在本地文件或数据库,定时去读取

(3)push模式:保存在nacos,监听变更实时更新

1.2 规则管理模式-原始模式

原始模式:控制台配置的规则直接推送到Sentinel客户端,也就是我们的应用。然后保存在内存中,服务重启则丢失

 

1.3 规则管理模式-pull模式

pull模式:控制台将配置的规则推送到Sentinel客户端,而客户端会将配置规则保存在本地文件或数据库中。以后会定时去本地文件或数据库中查询,更新本地规则。

 

1.4 规则管理模式-push模式

push模式:控制台将配置规则推送到远程配置中心,例如Nacos。Sentinel客户端监听Nacos,获取配置变更的推送消息,完成本地配置更新。

 

2. 实现push模式

push模式实现最为复杂,依赖于nacos,并且需要改在Sentinel控制台。整体步骤如下:

(1)修改order-service服务,使其监听Nacos配置中心

(2)修改Sentinel-dashboard源码,配置nacos数据源

(3)修改Sentinel-dashboard源码,修改前端页面

(4)重新编译、打包-dashboard源码

步骤一:修改order-service服务,使其监听Nacos配置中心

(1)引入依赖

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

(2)配置nacos地址

spring:  
  cloud:
    sentinel:
      datasource:
        flow:
          nacos:
            server-addr: localhost:8848 # nacos地址
            dataId: orderservice-flow-rules
            groupId: SENTINEL_GROUP
            rule-type: flow # 还可以是:degrade、authority、param-flow

步骤二:修改sentinel-dashboard源码,添加nacos数据源

sentinel-dashboard.jar(修改后源码)

sentinel-dashboard-1.8.1.jar(官方源码)

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

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

相关文章

【JVM】StringTable

String的基本特性 String&#xff1a;字符串&#xff0c;使用一对 ”” 引起来表示 String s1 “mogublog” ; // 字面量的定义方式String s2 new String(“moxi”); string声明为final的&#xff0c;不可被继承String实现了Serializable接口&#xff1a;表示字符串是支持序…

软件测试:随机测试

随机测试流程&#xff0c;自我积累&#xff0c;暂时作为base模板&#xff0c;后续会继续优化 ps&#xff1a;后续目标&#xff0c;可以完成随机测试-APP-模块初稿 1.发起随机测试 项目负责人发起随机测试&#xff0c;明确项目背景&#xff0c;筛选测试目标模块 随机测试的模…

计算机毕业设计php+vue基于微信小程序的音乐云系统-音乐播放系统

项目介绍 随着计算机技术的高速发展,现代计算机系统已经从以计算为中心向以信息化处理为中心的方向发展。如何充分利用互联网,这是大家共同关心的问题。本文主要介绍了关于音乐云微信小程序的实现方法,设计规划了音乐云微信小程序的网页,以互联网的形式将分散的用户进行统一管理…

数据库大作业——学生选课系统(基于SpringBoot+Mysql)

文章目录一、需求分析1、项目背景2、项目目标二、系统功能分析1、多角色划分2、模块功能详述三、系统架构1、技术选型2、系统分析3、架构设计4、系统演变四、数据库设计1、概念结构设计2、逻辑结构设计3、物理结构设计五、系统优化1、缓存2、池化技术3、读写分离4、后续优化3、…

Java项目中集成Redis提升系统的性能

概述 安装Redis 安装 启动Rocky Linux 9.0&#xff0c;在浏览器中打开web console. 如果没有安装Web console&#xff0c;按以下步骤安装启用&#xff1a; 安装命令&#xff1a; # dnf install cockpit 启用并运行服务 # systemctl enable --now cockpit.socket 开通防火墙&…

Xinlei cheng报告学习

上面是 下面是momuten encoder 关键词 variance 方差 asymmetric不对称 momentum encoder 动量 dimension维度 convergence收敛 symmetrizationsy均衡 contrastive learning 对比学习 autoregressive自回归 distillation蒸馏 没有 fc layer +bn 裁剪后variance方差变大 cum…

canvas截取多个视频的第一帧,第n秒画面

业务涉及视频预览&#xff0c;不点击视频则不播放而是先展示视频的画面给到用户 “因为本人特别喜欢梅艳芳&#xff0c;所以也留存了很多她的视频&#xff0c;这里就以她的视频做测试了” 截取多个视频的第一帧&#xff0c;使用&#xff1a;Promiseloadeddata事件canvas Pro…

如何提高测试的质量

一、需求与测试需求方面 1.应从产品人员手中获取需求&#xff0c;尽量要求产品人员对需求进行讲解(需求评审) 2.我们要做测试需求分析&#xff0c;并应用相对应的方法论&#xff0c;还要进行需求串讲 3.测试需求分析的方法&#xff1a;分解功能点&#xff0c;然后对每一个功…

数据分析思维(二)|相关思维

1、概念 相关思维是数据分析中最常见的思维之一&#xff0c;在我们观察指标变化的时候&#xff0c;往往需要观察指标之间的相关关系&#xff0c;比如观察自己身高和体重的变化&#xff0c;这就是一种相关思维的体现。 衡量指标之间的相关关系&#xff0c;常见的相关性分析方法…

[Linux打怪升级之路]-重定向

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、文件描述符 1、初…

步步详解IntelliJ IDEA创建springboot项目并运行

1. SpringBoot 简介 SpringBoot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。 我们在学习 Spring 的时候说过 Spring 框架是为了简化开发的&#xff0c;而 SpringBoot 是为了简化 Spring 开发的&#xff0c; 由此…

easylabel | 完美拯救手残党不会标注突出重点!(Label!~ Label!~)

1写在前面 我们在画图的时候经常需要标记某个值, 如散点图中的某个具体的点, 火山图中的某个基因, 但对于代码不太熟悉的小白来说, 还是有一定难度的.&#x1f92a; 本期和大家介绍一个基于shiny轻松进行label的包, 即easylabel包, 轻松实现交互式label, 麻麻再也不用担心你的画…

全国青少年软件编程(Scratch)等级考试二级考试真题2021年12月——持续更新.....

电子学会202112Scratc二级真题及参考答案 1.舞台上有3个角色,小猫的程序如下图所示,另外两个角色没有程序。点击绿旗,下列选项正确的是? A.小猫随鼠标移动,可能会遮挡其他两个角色 B.小猫随鼠标移动,可能会被其他两个角色遮挡 C.小猫不会随鼠标移动,更不会被遮挡 D.…

一睹风采,见证郁锦香酒店遍布全球核心城市的百变姿态

随着消费需求的不断升级&#xff0c;酒店消费场景也进行着多元化的发展&#xff0c;城市高端度假品牌正积极溯源消费需求&#xff0c;寻得品牌文化延伸的可靠路径。同时&#xff0c;各大酒店品牌也加快在市场布局的脚步&#xff0c;希望通过布局城市核心区域获得可持续发展的更…

企业微信-自建应用二:消息发送测试

1.开发过程 要测试企微自建应用的消息发送功能 企业微信开发者中心-调试工具 建立连接 corpsecret即是自建应用的Secret 输入参数&#xff0c;调用接口&#xff0c;即可拿到返回的token 发送应用消息 填写token&#xff0c;以及body消息体 {"touser": "Us…

Birdboot第二天

目录 V4 HttpServletRequest保存请求内容 1.此类专门处理请求 把获取请求的readline()和拆分代码移动过来 2.ClientHandler客户端处理器实例化HttpServletRequest 3. 拆分的信息从局部变量 变成属性 4.建方法 解析请求行 消息头 消息正文 V5 发送响应 1.在客户端处理器 …

非洲秃鹫优化算法:求解全局优化问题的一种新的自然启发元启发式算法(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 元启发式在解决优化问题中起着至关重要的作用。大多数此类算法的灵感来自于自然界中生物的集体智能和觅食。本文以非洲秃鹫的生…

YOLOv4:目标检测的最佳速度和精度

来源&#xff1a;投稿 作者&#xff1a;王同学 编辑&#xff1a;学姐 《YOLOv4&#xff1a;Optimal Speed and Accuracy of Object Detection》 发表时间及作者&#xff1a;2020 CVPR 目录 1.YOLOv4介绍 2.YOLOv4网络结构 2.1 Backbone改进 2.2 Neck改进 3.YOLOv4训练策…

java多线程基础

java多线程基础1. 线程是什么2. 线程的创建和运行方式1&#xff1a;继承Thread类示例:方式2&#xff1a;实现Runnable接口(推荐)示例:3. Thread类的常用方法4. 线程插队&#xff08;1&#xff09;yield 当前线程把时间片让给其它线程&#xff0c;不一定成功示例:&#xff08;2&…

数据库基础-Mongodb数据库复制操作

Mongodb数据库复制操作 关闭mongodb的服务,如下图 创建以下文件夹 现在我们开启三个服务,端口号为9927做为主节点,9928做为从节点,9929做为仲裁节点 仲裁节点的作用是协调leader选举&#xff0c;监测系统运行状态&#xff0c;提供节点互相通讯的数据信息。 开启主服务: m…