首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 Spring Cloud Alibaba Sentinel 的熔断降级保护微服务应用

使用 Spring Cloud Alibaba Sentinel 的熔断降级保护微服务应用

作者头像
张云飞Vir
发布2021-12-06 17:02:10
4580
发布2021-12-06 17:02:10
举报

1. 背景

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

1. Sentinel 介绍

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。

1.1 知识

Sentinel 的组成:

  • (1) Sentinel 核心库, 即基本的类库的使用。
  • (2) Dashboard 控制台,即web页面的使用。

核心库介绍

本章节主要说 核心库 的使用。

使用 Sentinel 来进行资源保护,主要分为几个步骤:

  • 定义资源
  • 定义规则
  • 检验规则是否生效

也就是说:

  • 先把可能需要保护的资源定义好(即埋点)
  • 之后再配置规则,规则描述了什么方式来保护资源。
  • 声明了资源,后续在任何时候灵活地定义各种流量控制规则。

资源

资源:可以是指一个服务,一个服务里的方法,或者是一段代码。写代码时,考虑某段代码是否需要保护,如果需要就将之定义为一个资源。

定义资源的方式

sentinel 支持都多种方式来定义资源,常见的有:

  • 方式一:整合到常见的主流框架,比如 Web Servlet、Dubbo、Spring Cloud
  • 方式二:抛出异常的方式,使用 SphU 这个类的 try-catch 方式
  • 方式三:返回布尔值方式定义资源,使用 SphO 提供 if-else 风格的 API
  • 方式四:注解方式定义资源,使用 @SentinelResource 注解 。
  • 方式五:异步调用支持,使用 SphU.asyncEntry 异步方法。

示例有: 抛出异常的方式 来定义资源 使用 SphU 这个类的 try-catch 风格的 API。当“资源”发生了限流之后会抛出 BlockException,然后捕捉异常进行限流之后的逻辑处理。

示例代码如下:

try (Entry entry = SphU.entry("resourceName")) {
  // 被保护的业务逻辑
  // do something here...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 在此处进行相应的处理操作
}

规则

Sentinel 支持以下几种规则:

  • 流量控制规则
  • 熔断降级规则
  • 系统保护规则
  • 来源访问控制规则
  • 热点参数规则

流量控制规则(FlowRule) 支持 QPS 模式(1)或并发线程数模式(0)。

熔断降级规则(DegradeRule) 熔断策略,支持慢调用比例/异常比例/异常数策略

系统保护规则 (SystemRule) 结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡

来源访问控制规则 (AuthorityRule) 即黑名单,白名单规则。

规则的持久化 建议和 nacos 一起使用,方法见本文后面章节。

1.2 在service层使用 Sentinel

一般java web 项目都会有 controller 层, service 层,dao层,我们要在 service 层使用的是可以这么做。

(1)添加依赖

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

(2) 在服务层加注解:

@Service
public class TestService {

    @SentinelResource(value = "sayHello")
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}

@SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 value 指示了一个资源名称。

@SentinelResource 还提供了其它额外的属性如 blockHandler,blockHandlerClass,fallback 用于表示限流或降级的操作

一般我们需要实现一个降级后的处理,比如上面的 fallback 指示一个降级后字符串返回值告知触发了熔断降级。

另外,Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。我们在后面用一个章节来介绍它。

1.3 和 Feign 一起使用

Sentinel 适配了组件。

(1) 先引入 spring-cloud-starter-alibaba-sentinel 的依赖 (2) 再引入feign依赖 引入 spring-cloud-starter-openfeign 依赖**,使 Sentinel starter 中的自动化配置类生效:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

(3) 配置文件打开 配置文件打开 Sentinel 对 Feign 的支持:

feign.sentinel.enabled=true

示例说明 比如下面的示例中你要了解的:

  • 1.正常的业务调用: /echo/{str}。
    1. 熔断后的异常处理,指定了 fallback 处理,并返回 "echo fallback" 字符串。

详细示例:

@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    String echo(@PathVariable("str") String str);
}

class FeignConfiguration {
    @Bean
    public EchoServiceFallback echoServiceFallback() {
        return new EchoServiceFallback();
    }
}

class EchoServiceFallback implements EchoService {
    @Override
    public String echo(@PathVariable("str") String str) {
        return "echo fallback";
    }
}

1.4 和 RestTemplate 一起使用

支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,加上 @SentinelRestTemplate 注解。

@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
    return new RestTemplate();
}

说明:@SentinelRestTemplate 注解的属性 @SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。

比如上面的示例指示了 ExceptionUtil.handleException 是熔断降级后的异常处理方法,该方面用明确的方法签名格式,如下:

public class ExceptionUtil {
    public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
        ...
    }
}

方法返回值提供了 SentinelClientHttpResponse 用于构造返回信息。

注意 应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常

实际项目中也会在网关层使用,见下一章节。

2. 在 Spring Cloud Gateway 网关中使用

可以结合 Spring Cloud Gateway 一起使用。

  • (1) 添加 spring-cloud-alibaba-sentinel-gateway 依赖。
  • (2) 添加 spring-cloud-starter-gateway 依赖 来让 spring-cloud-alibaba-sentinel-gateway 模块里的 Spring Cloud Gateway 自动化配置类生效:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

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

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  • (3) 配置文件 指定 spring.cloud.sentinel.filter.enabled 为 false

注意: 网关流控规则数据源类型是 gw-flow,若将网关流控规则数据源指定为 flow 则不生效。

支持两种资源标识维度的限流 Sentinel 提供的 Spring Cloud Gateway 的适配模块可以提供两种资源维度的限流:

  • routeId:即在 gateway 中的路由 routeId。
  • 自定义分组的名称:可以利用 API 来自定义一些分组名,将URL归类在一个组下。
  • 默认不支持 URL 粒度

3. sentinel 的控制台

3.1 Sentinel 控制台包含如下功能:

  • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
  • 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
  • 规则管理和推送:统一管理推送规则。
  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

3.2. 启动 sentinel 的控制台

下载最新版本的控制台 jar 包 可以从这个 release 页面 下载。

命令行启动

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar  -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456

说明:

  • -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080,浏览器从这个端访问。打开页面,默认用户名和密码都是 sentinel。

3.3. 规则管理

管理和新增规则 打开 http://localhost:8080 您可以在 控制台web页 配置修改规则,进行规则管理。

image.png

点击新增规则按钮,如下:

image.png

规则的存储 默认是存储在内存的,应用重启之后该规则会丢失。建议通过一些配置来使用外部存储方式来保存。建议结合 nacos 动态实时的刷新规则。

3.4. 规则推送

规则推送分为 3 种模式,包括:

  • 原始模式
  • Pull 模式
  • Push 模式"。

原始模式

通过 API 将规则推送至客户端并直接更新到内存中, 图例:

                             ------> sentinel 客户端1
Sentinel                     ------> sentinel 客户端2
Dashboard
                             ------> sentinel 客户端3

好处: 简单,无依赖; 坏处: 应用重启规则就会消失,不能用于生产环境

Pull模式

在客户端注册一个本地文件数据源:收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中。

本地文件数据源会定时轮询文件的变更,读取规则。

这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。

以本地文件数据源为例,过程如下图所示:

                                      /---------- 在内存中更新规则(规则缓存)
                                     /
Sentinel        ----->   Sentinel客户端     ----> 将规则写入本地文件   ----> 本地文件
Dashboard

好处:简单,不引入新的依赖 坏处:无法保证监控数据的一致性

Push模式

Sentinel 控制台 的规则到 统一配置中心(比如nacos),再到各个 客户端。

即: Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel

图例:

                       nacos
             (1)    /        \
                   /           \    (2)
                 /               \
Sentinel                          |----    sentinel 客户端1
Dashboard                         |----    sentinel 客户端2

生产环境建议使用 PUSH 模式,改造方法见下一章节。

4. 和 nacos 集成

4.1 介绍

默认情况下,规则是存储在内存的,重启后就没了。因此在生产环境建议使用nacos 集成来使用。分成两个步骤:

  • (1) 在sentinel dashboard 控制台的web管理页面创建规则,并将规则存储到nacs。需要改造sentinel 控制台。
  • (2) 客户端应用获得从 nacos 推送(PUSH)而来的 “限流的配置规则”,并加载到sentinel中。

即:在sentinel dashboard 的web页设置限流规则 ---> 规则存储到 nacos ---> 再推送到客户端应用

4.2 改造 sentinel 控制台

改造的目标是:改造 sentinel 控制台,使得在控制台的web页修改的规则保存到nacos中去。 具体改造方法:略。 有同学已经改造好的在这里:https://gitee.com/schonglin/sentinel-nacos

4.3 配置客户端,读nacos数据源。

实现的目标是:从nacos 读取规则并应用到客户端应用中。

4.3.1 修改客户端服务的配置文件,添加一个数据源

下面的示例中,我添加了一个 sentinel 的数据源 ds2, 指定了 nacos服务的地址,data-id 配置文件名,规则是 rule-type 限流类型。

spring:
  application:
    name: business
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080 # 指定控制台地址和端口
        port: 8721 # 这个端口和 Sentinel dashborad 做交互
      datasource:
        # 指定一个用于流控规则的数据源(来自nacos)
        ds2:
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            data-id: ${spring.application.name}-flow-rules  # 比如流控的规则是 {appName}-flow-rules
            group-id: SENTINEL_GROUP # 指定的一个分组名
            data-type: json
            rule-type: flow

4.3.2 在nacos中添加一个限流的配置文件,和数据源名称一致

我在nacos中添加一个限流的配置文件,名字叫做${spring.application.name}-sentinel-flow,它的格式和上面 data-id 要对应上。

[
    {
        "resource": "/hello",
        "limitApp": "default",
        "grade": 1,
        "count": 6,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

上面的配置内容说明:

  • resource:资源名
  • limitApp:调用来源, default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值,和上面的类型相关
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式

访问几次接口后,就可以在Sentinel Dashboard 中看到在nacos中配置的规则信息,重启后也可以再次重nacos获取到配置好的规则。

我的示例demo 见: https://github.com/vir56k/java_demo/tree/master/sentinel/sentineldemo3 配合 改造后支持nacos的sentinel 来使用。

5. 参考

Sentinel 控制台 https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0 https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81 https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8 https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel https://www.cnblogs.com/gyli20170901/p/11279576.html https://github.com/alibaba/Sentinel/wiki/Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0%EF%BC%88%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7%E7%AE%A1%E7%90%86%EF%BC%89#%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE https://blog.csdn.net/qq_38723394/article/details/108991518

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/9/29 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景
  • 1. Sentinel 介绍
    • 1.1 知识
      • 核心库介绍
      • 资源
    • 规则
      • 1.2 在service层使用 Sentinel
        • 1.3 和 Feign 一起使用
          • 1.4 和 RestTemplate 一起使用
          • 2. 在 Spring Cloud Gateway 网关中使用
          • 3. sentinel 的控制台
            • 3.1 Sentinel 控制台包含如下功能:
            • 3.2. 启动 sentinel 的控制台
              • 3.3. 规则管理
                • 3.4. 规则推送
                  • 原始模式
                    • Pull模式
                      • Push模式
                  • 4. 和 nacos 集成
                    • 4.1 介绍
                      • 4.2 改造 sentinel 控制台
                        • 4.3 配置客户端,读nacos数据源。
                          • 4.3.1 修改客户端服务的配置文件,添加一个数据源
                          • 4.3.2 在nacos中添加一个限流的配置文件,和数据源名称一致
                      • 5. 参考
                      相关产品与服务
                      对象存储
                      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档