MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

巧用 Sentinel 构建微服务熔断降级体系

2022-09-055.9k 阅读

微服务架构中的熔断降级需求

在微服务架构盛行的当下,一个大型应用被拆分成众多相互独立的微服务,各微服务之间通过网络相互调用。这种架构带来了诸多优势,如可扩展性强、技术栈灵活等,但同时也引入了新的挑战。其中,服务间调用的稳定性成为关键问题。由于微服务数量众多,网络环境复杂,任何一个微服务出现故障或响应延迟,都可能导致级联故障,最终使整个系统崩溃。

以电商系统为例,下单流程可能涉及商品服务、库存服务、支付服务等多个微服务。若库存服务因瞬时流量过大导致响应缓慢,调用它的下单服务线程会被长时间占用,随着请求不断涌入,下单服务的线程资源逐渐耗尽,进而影响到与下单服务相关的其他功能,如订单查询等,最终整个电商系统的可用性受到严重影响。

为了应对这类问题,熔断降级机制应运而生。熔断机制就像电路中的保险丝,当某个服务调用出现异常(如超时、失败率过高)达到一定阈值时,熔断器会“熔断”,暂时切断对该服务的调用,避免故障进一步蔓延。而降级则是在系统资源紧张或某个服务不可用时,暂时屏蔽一些非核心功能,优先保障核心业务的稳定运行。

Sentinel 概述

Sentinel 简介

Sentinel 是阿里巴巴开源的一款面向云原生微服务的流量控制、熔断降级和系统保护工具。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。Sentinel 具有丰富的功能特性,包括实时监控、动态规则配置、多种流量控制策略等。

Sentinel 的核心设计理念是将规则配置与业务逻辑解耦。通过统一的规则管理平台,运维人员可以方便地对各个微服务的限流、熔断等规则进行动态调整,而无需修改业务代码并重新部署。

Sentinel 的优势

  1. 易用性:Sentinel 提供了简单易用的 API 和注解,开发者可以快速将其集成到现有项目中。例如,在 Spring Boot 项目中,只需引入相应的依赖,配置少量参数,即可实现对接口的流量控制和熔断降级。
  2. 实时监控:Sentinel 具备强大的实时监控能力,能够实时展示每个资源的运行状态,如 QPS(每秒请求数)、响应时间、线程数、成功率等。通过这些监控数据,运维人员可以及时发现系统中的潜在问题,并针对性地调整规则。
  3. 动态规则配置:支持多种数据源进行规则配置,包括本地文件、远程配置中心(如 Nacos、Zookeeper)。这使得规则的更新无需重启应用,大大提高了系统的灵活性和可维护性。例如,当发现某个微服务的流量突然增大,可以通过配置中心实时调整限流规则,避免服务因过载而崩溃。

Sentinel 的核心概念

资源

在 Sentinel 中,资源是核心概念之一。它可以是一段代码块、一个方法、一个接口甚至是整个微服务。Sentinel 通过对资源进行监控和控制,实现对微服务的保护。例如,我们可以将商品查询接口定义为一个资源,对其进行流量控制和熔断降级。

规则

规则是 Sentinel 实现各种功能的基础。常见的规则包括流量控制规则、熔断降级规则、系统保护规则等。这些规则定义了在何种条件下对资源采取何种保护措施。例如,流量控制规则可以设置某个资源的 QPS 阈值,当请求量超过该阈值时,进行限流处理。

插槽链

Sentinel 的核心功能是通过插槽链实现的。插槽链由一系列插槽组成,每个插槽负责特定的功能,如统计、流量控制、熔断降级等。当请求进入时,会依次经过插槽链中的各个插槽,根据插槽的功能对请求进行处理。这种设计模式使得 Sentinel 的功能扩展非常方便,开发者可以根据需求自定义插槽并插入到插槽链中。

使用 Sentinel 构建熔断降级体系

引入 Sentinel 依赖

以 Spring Boot 项目为例,首先在 pom.xml 文件中引入 Sentinel 相关依赖:

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

如果需要使用 Sentinel 的控制台来管理规则,还需引入:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel - transport - servlet - api</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel - transport - servlet - common</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel - transport - servlet - webflux</artifactId>
</dependency>

定义资源

  1. 使用注解方式 在 Spring Boot 项目中,可以使用 @SentinelResource 注解来定义资源。例如:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @GetMapping("/example")
    @SentinelResource("exampleResource")
    public String exampleMethod() {
        return "This is an example response.";
    }
}

这里将 /example 接口定义为名为 exampleResource 的资源。

  1. 使用 API 方式 除了注解方式,也可以通过 Sentinel 的 API 来定义资源。例如:
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;

public class ExampleService {

    public void exampleMethod() {
        Entry entry = null;
        try {
            entry = SphU.entry("exampleResource");
            // 业务逻辑
            System.out.println("Executing business logic.");
        } catch (BlockException e) {
            // 处理限流、熔断等异常
            System.out.println("Blocked by Sentinel.");
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
}

配置熔断降级规则

  1. 基于异常比例熔断 基于异常比例熔断是指当某个资源的调用异常比例超过一定阈值时,触发熔断。在 Sentinel 控制台中,可以如下配置:
  • 资源名:填写之前定义的资源名称,如 exampleResource
  • 熔断策略:选择“异常比例”。
  • 阈值:设置异常比例阈值,例如 0.5,表示当异常比例达到 50% 时触发熔断。
  • 熔断时长:设置熔断的持续时间,单位为秒,如 10 秒。在这 10 秒内,所有对该资源的请求都会被熔断,直接返回错误信息。
  • 最小请求数:设置触发熔断的最小请求数,例如 100。只有当请求数达到 100 时,才会根据异常比例判断是否熔断。这是为了避免因请求数过少导致的误判。
  1. 基于慢调用比例熔断 慢调用比例熔断是指当某个资源的慢调用比例超过一定阈值时,触发熔断。在 Sentinel 控制台中,配置如下:
  • 资源名:同样填写定义的资源名称。
  • 熔断策略:选择“慢调用比例”。
  • 阈值:设置慢调用比例阈值,如 0.3,表示当慢调用比例达到 30% 时触发熔断。
  • 熔断时长:设置熔断持续时间。
  • 最小请求数:设置触发熔断的最小请求数。
  • 慢调用响应时间:设置慢调用的响应时间阈值,例如 500 毫秒。当请求的响应时间超过 500 毫秒时,被认为是慢调用。

处理熔断降级后的请求

当熔断发生后,需要给调用方一个合适的响应,避免调用方长时间等待。在 @SentinelResource 注解中,可以通过 fallback 属性指定降级处理方法。例如:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @GetMapping("/example")
    @SentinelResource(value = "exampleResource", fallback = "fallbackMethod")
    public String exampleMethod() {
        // 模拟可能出现异常的业务逻辑
        int result = 10 / 0;
        return "This is an example response.";
    }

    public String fallbackMethod() {
        return "Service is currently unavailable, please try again later.";
    }
}

exampleResource 触发熔断时,会调用 fallbackMethod 方法,返回友好的提示信息给调用方。

Sentinel 与其他组件的集成

Sentinel 与 Spring Cloud Gateway 集成

Spring Cloud Gateway 是 Spring Cloud 生态中的网关组件,负责对请求进行路由和过滤。将 Sentinel 与 Spring Cloud Gateway 集成,可以实现对网关层的流量控制和熔断降级。

  1. 引入依赖 在 Spring Cloud Gateway 项目的 pom.xml 文件中引入 Sentinel 网关依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud - starter - alibaba - sentinel - gateway</artifactId>
</dependency>
  1. 配置 Sentinel 过滤器application.yml 文件中配置 Sentinel 网关过滤器:
spring:
  cloud:
    sentinel:
      gateway:
        enabled: true
        block - handler - class: com.example.gateway.SentinelGatewayBlockHandler
        block - handler: handleBlock

这里指定了自定义的 SentinelGatewayBlockHandler 类及其 handleBlock 方法来处理被 Sentinel 限流或熔断的请求。

  1. 定义资源和规则 可以通过 Sentinel 控制台为网关中的路由定义资源和规则。例如,为 /api/user 路由定义流量控制规则,限制其 QPS 为 100。这样可以有效保护后端微服务,避免因网关层流量过大导致后端服务崩溃。

Sentinel 与 Dubbo 集成

Dubbo 是一款高性能的 Java RPC 框架,广泛应用于微服务架构中。将 Sentinel 与 Dubbo 集成,可以对 Dubbo 服务的调用进行流量控制和熔断降级。

  1. 引入依赖 在 Dubbo 项目的 pom.xml 文件中引入 Sentinel 与 Dubbo 的集成依赖:
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel - adapter - dubbo - spi</artifactId>
</dependency>
  1. 配置 Sentinel 过滤器 在 Dubbo 的配置文件(如 dubbo.xmlapplication.yml)中配置 Sentinel 过滤器:
<dubbo:provider filter="sentinel.dubbo.provider"/>
<dubbo:consumer filter="sentinel.dubbo.consumer"/>

通过配置这两个过滤器,分别对 Dubbo 服务的提供者和消费者进行保护。

  1. 定义资源和规则 可以在 Sentinel 控制台为 Dubbo 服务定义资源和规则。例如,为某个 Dubbo 服务的方法定义熔断降级规则,当调用失败率达到 40% 时,触发熔断 5 秒。这样可以确保 Dubbo 服务在出现故障时,不会影响到整个微服务系统的稳定性。

Sentinel 的高级应用场景

热点参数限流

热点参数限流是 Sentinel 特有的功能,它可以针对请求中的热点参数进行限流。例如,在电商系统中,某个商品的查询接口,不同的商品 ID 可能会有不同的访问热度。通过热点参数限流,可以对访问热度高的商品 ID 进行更严格的限流。

  1. 配置热点参数限流规则 在 Sentinel 控制台中,选择要配置的资源,然后在“流量控制”中选择“热点参数限流”。例如,对于商品查询接口 /product/{productId},可以配置针对 productId 参数的限流规则:
  • 资源名:填写商品查询接口对应的资源名称。
  • 参数索引:根据方法参数顺序,指定 productId 的索引位置,如 0。
  • 单机阈值:设置针对该参数的单机 QPS 阈值,例如 100,表示对于某个特定的 productId,每秒最多允许 100 次请求。
  • 统计窗口:设置统计时间窗口,单位为秒,如 1 秒。
  1. 代码实现 在使用 @SentinelResource 注解定义资源时,可以通过 blockHandler 等属性处理热点参数限流后的请求。例如:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @GetMapping("/product/{productId}")
    @SentinelResource(value = "productResource", blockHandler = "handleProductBlock")
    public String getProduct(@PathVariable String productId) {
        return "Product information for productId: " + productId;
    }

    public String handleProductBlock(String productId, BlockException ex) {
        return "Product access is limited due to high traffic for productId: " + productId;
    }
}

系统自适应保护

系统自适应保护是 Sentinel 的一项重要功能,它可以根据系统的负载情况,自动调整限流和熔断规则,以保障系统的整体稳定性。

  1. 系统保护规则配置 在 Sentinel 控制台中,可以配置系统保护规则。主要参数包括:
  • 最大 QPS:设置系统允许的最大 QPS,当系统的 QPS 超过该值时,Sentinel 会自动触发限流。
  • CPU 使用率:设置系统 CPU 使用率的阈值,当 CPU 使用率超过该阈值时,进行限流。例如,设置为 0.8,表示当 CPU 使用率达到 80% 时,开始限流。
  • 平均响应时间:设置系统平均响应时间的阈值,当平均响应时间超过该值时,触发限流。
  1. 工作原理 Sentinel 通过实时监控系统的各项指标(如 QPS、CPU 使用率、平均响应时间等),与配置的阈值进行比较。当指标超过阈值时,会根据预设的策略对资源进行限流或熔断,以降低系统负载,保证系统的可用性。例如,当系统 CPU 使用率过高时,Sentinel 会自动降低一些非核心业务的流量,优先保障核心业务的运行。

实践中的注意事项

规则的合理配置

  1. 阈值的设置 在配置限流和熔断规则时,阈值的设置至关重要。如果阈值设置过高,可能无法起到有效的保护作用;如果设置过低,则可能导致服务无法正常提供。例如,在配置流量控制规则的 QPS 阈值时,需要根据服务的性能测试结果和实际业务场景来确定。如果服务在正常情况下的 QPS 为 500,且有一定的流量突发空间,可以将阈值设置为 800 - 1000。对于熔断规则的异常比例和慢调用比例阈值,也需要结合历史数据和业务容忍度来设置。

  2. 规则的继承和覆盖 在 Sentinel 中,规则可以存在继承和覆盖关系。例如,在全局配置了某个资源的基本限流规则后,还可以针对特定的环境(如生产环境、测试环境)或特定的调用方配置更详细的规则。在配置时,需要注意规则的优先级,避免出现规则冲突导致的意外情况。

监控与调优

  1. 利用监控数据 Sentinel 的实时监控功能提供了丰富的数据,包括资源的 QPS、响应时间、成功率等。运维人员和开发人员应定期查看这些监控数据,分析系统的运行状况。例如,如果发现某个资源的响应时间突然变长,可能是该资源对应的微服务出现了性能问题,需要进一步排查原因。通过监控数据,还可以评估规则配置的合理性,及时调整规则。

  2. 性能调优 虽然 Sentinel 的设计目标是对系统性能影响最小化,但在高并发场景下,仍可能对系统性能产生一定影响。为了优化性能,可以采取一些措施,如合理设置插槽链,避免不必要的插槽;对频繁调用的资源进行缓存处理等。同时,定期对系统进行性能测试,确保在引入 Sentinel 后,系统性能仍能满足业务需求。

故障演练

  1. 模拟故障场景 为了确保熔断降级体系在实际故障发生时能够正常工作,需要进行故障演练。可以通过工具(如 Chaos Monkey)模拟微服务故障、网络延迟等场景,观察 Sentinel 的熔断降级机制是否生效。例如,模拟某个微服务的响应延迟达到 1 秒,观察 Sentinel 是否会根据慢调用比例熔断规则进行熔断。

  2. 验证恢复机制 除了验证熔断机制,还需要验证服务在熔断后的恢复机制。当故障排除后,Sentinel 应能够及时恢复对服务的正常调用。在故障演练中,检查服务在熔断时长结束后,是否能够重新接收请求并正常处理,确保系统的高可用性。