前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于 Sentinel 作熔断

基于 Sentinel 作熔断

作者头像
程序猿Damon
发布2020-05-25 16:26:37
8010
发布2020-05-25 16:26:37
举报

我们都知道Spring cloud 作熔断降级的组件 Hystrix,Spring cloud 之熔断机制(实战)一文中,也讲述了如何使用 Hystrix,这是大家一直耳熟能详的。其实阿里的一款神器 Sentinel,也可以提供熔断降级的功能。

Sentinel简介

随着微服务的发展,服务们之间的稳定性变得越来越重要。Sentinel 以流量作为切入点,从流量控制、熔灾降级、系统负载保护等多个维度来保护服务的稳定性。Sentinel 具有以下特征:完备的实时监控、广泛的开源生态、完善的 SPI 扩展点、积累丰富的场景。

首先,我们先简单看看 Sentinel 与 Hystrix 的区别:

功能

Sentinel

Hystrix

隔离策略

信号量隔离策略

线程池/信号量隔离策略

熔断降级

基于响应时间、异常次数或异常比例

基于异常比例

动态规则配置

支持多数据源

支持多数据源

限流

基于QPS

有限的支持

系统自适应保护

支持

不支持

控制台管理

可配置规则、查看监控、服务发现等

简单的链路监控查看

基于注解的支持

支持

支持

处理规则

支持预热、匀速器、排队模式

不支持

扩展性

多个扩展

插件形式

上面看到 Sentinel 能实现的功能也很多的,而且在熔断方面跟 Hystrix 差不多,甚至更好,所以接下来我们看看利用 Sentinel 来实现熔断的逻辑。

首先,服务生产者还是按照 Spring Cloud Kubernetes之实战二服务注册与发现 一文来进行,这里利用了简单的k8s作为服务的注册与发现功能。跟

eureka、zk、nacos 等配置都基本类似。只不过这里不用那些了,只用k8s来处理即可。

对于服务消费者,首先配置依赖:

代码语言:javascript
复制
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/>
    </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <swagger.version>2.6.1</swagger.version>
    <xstream.version>1.4.7</xstream.version>
    <pageHelper.version>4.1.6</pageHelper.version>
    <fastjson.version>1.2.51</fastjson.version>
    <springcloud.version>Greenwich.SR4</springcloud.version>
    <!-- <springcloud.version>2.1.8.RELEASE</springcloud.version> -->
    <springcloud.kubernetes.version>1.1.1.RELEASE</springcloud.kubernetes.version>
    <mysql.version>5.1.46</mysql.version>
    <springcloud.alibaba.version>0.2.2.RELEASE</springcloud.alibaba.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${springcloud.alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${springcloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-undertow</artifactId>
    </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <!-- spring-cloud-starter-oauth2包含了 spring-cloud-starter-security -->
        <!-- <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency> -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        </dependency>

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

    <!-- springcloud-k8s-discovery -->

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

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-discovery</artifactId>
        </dependency>

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

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
</dependencies>

接下来就需要配置 Sentinel 的监听:

代码语言:javascript
复制
spring:
  application:
    name: operate-git-service
  cloud:
    sentinel:
      enabled: true #Sentinel自动化配置是否生效
      eager: true #取消Sentinel控制台懒加载
      log:
        dir: /data/sentinel/logs #Sentinel日志文件所在的目录
      transport:
        dashboard: localhost:8080 #sentinel的Dashboard地址
        heartbeatIntervalMs: 500 #应用与Sentinel控制台的心跳间隔时间 or heartbeat-interval-ms
        port: 8719

以上配置完成后,我们写一个测试类 TestController:

代码语言:javascript
复制
@GetMapping(value = "/getUser")
//@SentinelResource(value = "hello",blockHandler = "apiBlockHandlerException", blockHandlerClass = MyExceptionUtil.class) //fallback = "testFallBack"
public Response<Object> getUser() {
  return gitClientService.getUser();
}

接着写一个Service:

代码语言:javascript
复制
@SentinelResource(value = "hello",blockHandler = "apiBlockHandlerException", blockHandlerClass = MyExceptionUtil.class, fallback = "testFallBack")
@Override
public Response<Object> getUser() {
  return Response.ok(200, 0, "success", "data");
}

public Response<Object> testFallBack() {
  return Response.ok(200, -5, "testFallBack ...", null);
}

限流异常处理类:
public class MyExceptionUtil {
  /**
   *
   * @author Damon
   * @date 2020年3月24日
   *
   */

  /**
   * 
   * 基于API函数的限流
   * @param ex
   * @return
   * @author Damon 
   * @date 2020年3月24日
   *
   */
  public static Response<Object> apiBlockHandlerException(BlockException ex) {
    return Response.ok(200, -4, "block 。。。。", null);
  }
 }

大家可以发现,controller 与 service 中都可以有注解 @SentinelResource,而且在 Spring cloud 之多种方式限流(实战)一文中,我们知道 Sentinel 默认为所有的 HTTP 服务提供限流埋点,而且有默认的限流提示(对于接口),只需要控制配置限流规则即可。这里,我们加了 @SentinelResource,其提供了属性 blockHandler、blockHandlerClass 限流的处理逻辑,同时,该注解也提供了 fallback 属性可以直接加熔断的处理函数。

同样,我们先打开 Sentinel 的Dashboard,看看其服务实时监控(如果没有则先请求几个接口):

请求的几个簇点链路:

我们可以针对函数本身作任何的规则设置,也可以针对注解@SentinelResource资源来进行设置规则:

发现,对于方法,直接加限流或降级规则设置后,其返回的结果都是:

代码语言:javascript
复制
Blocked by Sentinel (flow limiting)

而对于注解 @SentinelResource,设置限流规则:

访问其接口时,发现返回:

代码语言:javascript
复制
{"message":{"status":200,"code":-4,"message":"block 。。。。"},"data":null}

设置熔断规则:

访问后,返回:

代码语言:javascript
复制
{"message":{"status":200,"code":-5,"message":"testFallBack ..."},"data":null}

从上面的测试结果来看:

  • Sentinel 默认给所有的Http服务 设下埋点,只要定义好规则(限流、熔断),其都会按照规则执行,并且返回默认的信息: Blocked by Sentinel (flow limiting)
  • Sentinel 中设置的注解 @SentinelResource 中,包括属性 value、blockHandler、blockHandlerClass、fallback,其中中间两个是对限流定义的类与其出路逻辑函数,而 fallback 是针对熔断规则设置的处理函数。
  • 设置的规则中,限流的处理函数中,必须要有BlockException ex 这个参数,返回值要与原函数的返回值一致。而熔断的处理函数中,其函数的参数与返回值必须与原函数的都完全一致。

OK,Sentinel 作为熔断机制来处理,操作结束。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 交个朋友之猿天地 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档