基于 Sentinel 作熔断 | 文末赠资料

点击上方蓝色“程序猿Damon”,选择“设为星标”

回复“yeah”获取整理的学习资料

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

Sentinel简介

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

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

功能SentinelHystrix
隔离策略信号量隔离策略线程池/信号量隔离策略
熔断降级基于响应时间、异常次数或异常比例基于异常比例
动态规则配置支持多数据源支持多数据源
限流基于QPS有限的支持
系统自适应保护支持不支持
控制台管理可配置规则、查看监控、服务发现等简单的链路监控查看
基于注解的支持支持支持
处理规则支持预热、匀速器、排队模式不支持
扩展性多个扩展插件形式

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

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

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

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

<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 的监听:

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:

@GetMapping(value = "/getUser")
//@SentinelResource(value = "hello",blockHandler = "apiBlockHandlerException", blockHandlerClass = MyExceptionUtil.class) //fallback = "testFallBack"
public Response<Object> getUser() {
  return gitClientService.getUser();
}

接着写一个Service:

@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资源来进行设置规则:

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

Blocked by Sentinel (flow limiting)

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

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

{"message":{"status":200,"code":-4,"message":"block 。。。。"},"data":null}

设置熔断规则:

访问后,返回:

{"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 作为熔断机制来处理,操作结束。

整理了一些大厂的面试资料以及 Java进阶学习资料,获取方式:关注此关注号,回复“面试题”、“Java进阶”,获取海量大厂的资料。

 

个人网站:http://www.damon8.cn

 

热文推荐

微服务自动化部署CI/CD

基础设施服务k8s快速部署之HA篇

今天被问微服务,这几点,让面试官刮目相看

Spring cloud 之多种方式限流(实战)

Spring cloud 之熔断机制(实战)

面试被问finally 和 return,到底谁先执行?

Go语言入门基础之库源码文件

Go语言入门基础之命令源码文件

Springcloud Oauth2 HA篇

Spring Cloud Kubernetes之实战一配置管理

Spring Cloud Kubernetes之实战二服务注册与发现

Spring Cloud Kubernetes之实战三网关Gateway

求关注

关注公众号,回复入群,获取更多惊喜!公众号(程序猿Damon)里回复 ES、Flink、Java、Kafka、MQ、ML、监控、大数据、k8s 等关键字可以查看更多关键字对应的文章。

如有收获,点个在看,谢谢

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值