微服务中间件--微服务保护

这篇具有很好参考价值的文章主要介绍了微服务中间件--微服务保护。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

微服务保护

a.sentinel

雪崩问题

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

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

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

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监控

b.sentinel限流规则

簇点链路

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

需求:给 /order/{orderId}这个资源设置流控规则,QPS不能超过 5。然后利用jemeter测试。

1.设置流控规则:

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

2.jemeter测试:
微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

1) 流控模式

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

1.a) 关联模式
  • 关联模式:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
  • 使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是优先对支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

需求:

  • 在OrderController新建两个端点:/order/query和/order/update,无需实现业务
  • 配置流控规则,当/order/ update资源被访问的QPS超过5时,对/order/query请求限流

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

  • 两个有竞争关系的资源
  • 一个优先级较高,一个优先级较低
1.b) 链路模式

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

例如有两条请求链路:

  • /test1 -> /common
  • /test2 -> /common

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

需求:

有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流。

步骤:

  • 1.在OrderService中添加一个queryGoods方法,不用实现业务
  • 2.在OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法
  • 3.在OrderController中添加一个/order/save的端点,调用OrderService的queryGoods方法
  • 4.给queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS必须小于2

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

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

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

spring:
	cloud:
		sentinel:
			web-context-unify: false # 关闭context整合

2) 流控效果

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

2.a) 预热模式

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

案例:需求:给/order/{orderId}这个资源设置限流,最大QPS为10,利用warm up效果,预热时长为5秒

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

2.b) 排队等待

排队等待是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

3) 热点参数限流

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

  • 如果参数值是100,则每1秒允许的QPS为10
  • 如果参数值是101,则每1秒允许的QPS为15

案例:给/order/{orderId}这个资源添加热点参数限流,规则如下:

  • 默认的热点参数规则是每1秒请求量不超过2
  • 给102这个参数设置例外:每1秒请求量不超过4
  • 给103这个参数设置例外:每1秒请求量不超过10

热点参数限流对默认的SpringMVC资源无效,只对添加@SentinelResource注解的方法产生效果

@SentinelResource("hot")
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
    // 根据id查询订单并返回
    return orderService.queryOrderById(orderId);
}

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

c.隔离和降级

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

1) Feign整合Sentinel

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

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

feign:
  sentinel:
    enabled: true # 开启Feign的Sentinel功能

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

  • 方式一:FallbackClass,无法对远程调用的异常做处理
  • 方式二:FallbackFactory,可以对远程调用的异常做处理 (推荐)

步骤一:在feing-api项目的clients.fallback中定义类,实现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:

public class DefaultFeignConfiguration {
    @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);
}

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

2) 线程隔离

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

  • 线程池隔离
  • 信号量隔离QPS(Sentinel默认采用)

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

线程池隔离

  • 优点:
    • 支持主动超时
    • 支持异步调用
  • 缺点
    • 线程的额外开销比较大
  • 场景
    • 低扇出

信号量隔离

  • 优点:
    • 轻量级,无额外开销
  • 缺点:
    • 不支持主动超时
    • 不支持异步调用
  • 场景
    • 高频调用
    • 高扇出
2.a) 线程隔离(舱壁模式)

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

  • QPS:就是每秒的请求数,在快速入门中已经演示过
  • 线程数:是该资源能使用用的tomcat线程数的最大值。也就是通过限制线程数量,实现舱壁模式。

案例:给 UserClient的查询用户接口设置流控规则,线程数不能超过 2

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

3) 熔断降级

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

案例:给 UserClient的查询用户接口设置降级规则,慢调用的RT阈值为50ms,统计时间为1秒,最小请求数量为5,失败阈值比例为0.4,熔断时长为5s

提示:为了触发慢调用规则,我们需要修改UserService中的业务,增加业务耗时:

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

3.b) 熔断策略-异常比例、异常数

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

案例:给 UserClient的查询用户接口设置降级规则,统计时间为1秒,最小请求数量为5,失败阈值比例为0.4,熔断时长为5s

提示:为了触发异常统计,我们需要修改UserService中的业务,抛出异常:

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

d.授权规则及规则持久化

1) 授权规则

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

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

从request中获取一个名为origin的请求头,作为origin的值:

在order-service中创建sentinel包

package cn.itcast.order.sentinel;

@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:
    gateway:
      default-filters:
        - AddRequestHeader=Truth, ABCDEFGHIJKLMN
        - AddRequestHeader=origin, gateway # 添加名为origin的请求头,值为gateway

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

2) 自定义异常结果

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

微服务中间件--微服务保护,微服务中间件,微服务,中间件,架构,java,spring cloud

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

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

在order-service的sentinel包中定义类,实现BlockExceptionHandler接口:

package cn.itcast.order.sentinel;

@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 + "}");
    }
}

3) 规则持久化

3.a) 规则管理模式

Sentinel的控制台规则管理有三种模式:文章来源地址https://www.toymoban.com/news/detail-661866.html

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

到了这里,关于微服务中间件--微服务保护的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成

    Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成

    目录 前言 源码地址 官方中文文档 使用版本 spring Spring Boot 3.1.0 中间件 使用到的组件与功能 环境安装 虚拟机 nexus nacos 集成过程 工程搭建 父工程搭建 子工程 服务集成 nacos集成 配置文件 服务注册与发现-discovery 服务注册 启动 服务发现 测试 配置管理-config 新增配置  测试

    2024年02月07日
    浏览(17)
  • spring cloud 搭建消息中间件 RabbitMQ 环境、Mac/Windows下载安装RabbitMQ、配置RabbitMQ环境变量

    spring cloud 搭建消息中间件 RabbitMQ 环境、Mac/Windows下载安装RabbitMQ、配置RabbitMQ环境变量

    spring boot、spring cloud工程:Mac/Windows下载安装Erlang、RabbitMQ,并配置环境变量。 这里学习如何安装 RabbitMQ,因为远程配置中心的动态更新需要结合 RabbitMQ 来使用。 这里给出自己下载和使用的百度网盘链接:Erlang 版本为25.3.2、RabbitMQ版本为3.12.1 : 链接:百度网盘链接 提取码:

    2024年02月15日
    浏览(9)
  • java后端技术汇总 + 中间件 + 架构思想

    1. 华为OD机考题 + 答案 2023华为OD统一考试(A+B卷)题库清单-带答案(持续更新) 2023年华为OD真题机考题库大全-带答案(持续更新) 2. 面试题 一手真实java面试题:2023年各大公司java面试真题汇总--持续更新 3. 技术知识 java后端技术汇总 + 中间件 + 架构思想 类型 难度 Spring、

    2024年02月13日
    浏览(12)
  • Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成
Sleuth+Zipkin集成分布式链路追踪

    Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成 Sleuth+Zipkin集成分布式链路追踪

    目录 前言 源码地址 官方中文文档 使用版本 spring Spring Boot 3.1.0 中间件 使用到的组件与功能 环境安装 虚拟机 nexus nacos 集成过程 工程搭建 父工程搭建 子工程 服务集成 nacos集成 配置文件 服务注册与发现-discovery 服务注册 启动 服务发现 测试 配置管理-config 新增配置  测试

    2024年02月12日
    浏览(43)
  • 如何利用容器与中间件实现微服务架构下的高可用性和弹性扩展

    本文分享自天翼云开发者社区《如何利用容器与中间件实现微服务架构下的高可用性和弹性扩展》,作者:c****w 在当今的互联网时代,微服务架构已经成为许多企业选择的架构模式,它能够提高系统的灵活性、可维护性和可扩展性。然而,微服务架构下的高可用性和弹性扩展

    2024年01月19日
    浏览(48)
  • Java分布式微服务4——异步服务通讯(RabbitMQ)中间件

    Java分布式微服务4——异步服务通讯(RabbitMQ)中间件

    为什么需要异步调用? 故障隔离 :支付服务不负责调用其他三个服务,只负责通知Broker支付成功这个事件,然后就返回结果,后面的服务故障了和前面发布事件的服务无关,前面的服务发布完事件就结束了 吞吐量提升 :Broker将支付成功的事件广播给订阅了这个事件的那些服

    2024年02月13日
    浏览(13)
  • 【系统架构设计】架构核心知识: 1 构件和中间件

    目录 一 构件 1 构件的特性 2 构件、对象和模块的对比  3 构件的复用

    2024年02月07日
    浏览(16)
  • 中间件:构建现代软件架构的桥梁

            在当今快速发展的科技领域中,软件系统的复杂性不断增加。为了应对这一挑战,中间件应运而生,成为连接和协调不同软件组件的不可或缺的桥梁。本文将深入探讨中间件的基本概念、作用以及一些常见的中间件类型。         中间件 是指介于操作系统和应

    2024年01月23日
    浏览(15)
  • 软件架构设计(十三) 构件与中间件技术

    软件架构设计(十三) 构件与中间件技术

    中间件的定义 其实中间件是属于构件的一种。是一种独立的系统软件或服务程序,可以帮助分布式应用软件在不同技术之间共享资源。 我们把它定性为一类系统软件,比如我们常说的消息中间件,数据库中间件等等都是中间件的一种体现。一般情况都是给应用系统提供服务

    2024年02月07日
    浏览(11)
  • 系统架构设计高级技能 · 构件与中间件技术

    系统架构设计高级技能 · 构件与中间件技术

    点击进入系列文章目录 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 定义1: 软件构件是一种组装单元,它具有规范的接口规约和显式的语境依赖。软件构件可以被独立地部署并由第三方

    2024年02月07日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包