Spring Cloud总结29.Zuul的FallBack回退机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud总结29.Zuul的FallBack回退机制相关的知识,希望对你有一定的参考价值。


接上篇《​​28.Zuul的Filter过滤器​​》  Spring Cloud版本为Finchley.SR2版

上一篇我们介绍了有关Zuul的Filter过滤器禁用的相关知识,本篇我们来继续学习有关Zuul回退的相关知识。
本部分官方文档:​​​https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html#hystrix-fallbacks-for-routes​​ 注:好像Finchley.SR2的文档已经挂了,最新的是Finchley.SR4的文档。

一、Zuul的代理服务断路器触发试验

通过前面的几个章节我们知道,在默认情况下,经过Zuul的请求都会被Hystrix包裹,即Zuul的所有请求在Hystrix Command中执行,所以Zuul本身就具有断路器的功能。

我们在讲解Zuul的退回机制之前,我们前做一个断路器触发的试验。

首先启动我们之前搭建的Eureka Server、User微服务以及Zuul服务:

【Spring


然后之前也在Zuul中配置了User的别名映射:

zuul:
ignored-services: *
routes:
microserver-provider-user: /user/**

然后我们通过Zuul网关代理访问User服务,是没问题的:

【Spring


因为经过Zuul的请求都会被Hystrix包裹,那么我们直接访问Zuul的Hystrix端点(http://localhost:8040/actuator/hystrix.stream),应该是可以的:

【Spring


那同理,我们用之前搭建的Hystrix Dashboard服务,可以对Zuul的Hystrix端点进行可视化查看,我们启动之前编写的Hystrix Dashboard服务,并查看Zuul的Hystrix端点:

【Spring

【Spring

【Spring


在上面的监控图中,之前我们解释过各种参数的意义(详见之前的博文:​​javascript:void(0)​​),我们可以看到这里Circuit的状态为“Closed”,即当前断路器的状态为关闭状态,也就是说没有请求是异常触发了断路器的。

我们此时将User微服务停掉,然后不停的刷新user的findById服务,我们可以看到断路器就被打开了:

【Spring

【Spring


我们可以看到当被代理的服务为异常的情况时,此时反馈的信息为 “SHORTCIRCUIT”(翻译为“短路”),很不友好。此时我们想要像之前直接使用Hystrix一样,为代理的服务也设置异常回退的Fallback方法,怎么来实现呢?这就用到了Zuul的回退机制。

二、Zuul的退回机制

我们来为上面代理的User的服务设置异常回退的Fallback方法。
首先我们在Zuul的工程下,创建Zuul的全局回退的provider类“MyFallbackProvider”,该类继承了FallbackProvider父类:

package com.microserver.cloud;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;

import com.netflix.hystrix.exception.HystrixTimeoutException;

public class MyFallbackProvider implements FallbackProvider

@Override
public String getRoute()
return "microserver-provider-user";


@Override
public ClientHttpResponse fallbackResponse(String route, final Throwable cause)
if (cause instanceof HystrixTimeoutException)
return response(HttpStatus.GATEWAY_TIMEOUT);
else
return response(HttpStatus.INTERNAL_SERVER_ERROR);



private ClientHttpResponse response(final HttpStatus status)
return new ClientHttpResponse()
@Override
public HttpStatus getStatusCode() throws IOException
return status;


@Override
public int getRawStatusCode() throws IOException
return status.value();


@Override
public String getStatusText() throws IOException
return status.getReasonPhrase();


@Override
public void close()


@Override
public InputStream getBody() throws IOException
return new ByteArrayInputStream("fallback".getBytes());


@Override
public HttpHeaders getHeaders()
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;

;

先不具体解释这段代码,我们先来看一下FallbackProvider父类的源码(这里我将源码中的英文注释翻译了一下):

package org.springframework.cloud.netflix.zuul.filters.route;
import org.springframework.http.client.ClientHttpResponse;

/**
* 当路由上发生故障时提供回退。
*
* @author Ryan Baxter
* @author Dominik Mostek
*/
public interface FallbackProvider
/**
* 这里返回的是回退将用到的路由。
* @return The route the fallback will be used for.
*/
public String getRoute();

/**
* 根据执行失败的原因提供回退响应
*
* @param route The route the fallback is for
* @param cause cause of the main method failure, may be <code>null</code>
* @return the fallback response
*/
ClientHttpResponse fallbackResponse(String route, Throwable cause);

我们通过源码的注释可以知晓,继承FallbackProvider父类,将实现“getRoute”以及“fallbackResponse”方法。其中“getRoute”方法返回一个回退时需要用到的路由,也就是我们代理的服务的路由名称。而“fallbackResponse”方法就是我们需要按照实际需要,给不同的失败原因,返回不同的响应。

那么回到我们前面的代码,该代码的“getRoute”方法,提供的路由为“microserver-provider-user”,即我们microserver-provider-user微服务的路由。如果要为所有路由提供默认回退,可以创建FallbackProvider类型的bean并使getRoute方法返回*或null。
然后fallbackResponse方法中,我们分析了断路器异常类型中的“HttpStatus.GATEWAY_TIMEOUT”以及“HttpStatus.INTERNAL_SERVER_ERROR”异常类型,然后分类通过response方法,返回一个ClientHttpResponse对象,该对象中会返回这个请求的回退响应信息,分别是响应状态对象“StatusCode”、状态码“RawStatusCode”、异常体信息“Body”以及响应头“Headers”,这里我们响应的ContentType类型为Json类型(MediaType.APPLICATION_JSON)。然后我们在启动配置类中注入这个Bean:

package com.microserver.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
public class MircoserverGateWayZuulApplication
@Bean
public RiskCheckFilter riskCheckFilter()
return new RiskCheckFilter();


@Bean
public MyFallbackProvider myFallbackProvider()
return new MyFallbackProvider();


public static void main(String[] args)
SpringApplication.run(MircoserverGateWayZuulApplication.class, args);

我们重启一下Zuul,在User停机的状态下重新访问User的findById服务:

【Spring


可以看到,现在不直接响应异常页面的,响应的信息为“fallback”,即之前我们编写的getBody()方法的返回值:

@Override
public InputStream getBody() throws IOException
return new ByteArrayInputStream("fallback".getBytes());

我们在MyFallbackProvider的fallbackResponse方法中打一个断点,用Debug的方式重新运行Zuul服务,然后访问User的findById服务,看看接收的异常是什么类型的:

【Spring


我们可以看到,当前接收到的cause不是HystrixTimeoutException类型,即不是访问超时,那么就可以判断我们代理的微服务是有问题的,即可以反馈服务异常(这里的INTERNAL_SERVER_ERROR的响应码为500,响应信息为"Internal Server Error",详细类型和响应码,详见HttpStatus枚举类源码)。实际上通过“Load balancer does not have available server for client: microserver-provider-user”异常信息我们也可以得知访问的微服务已经没有可用的负载均衡器了,说明user服务已经挂了。

我们把上面的response方法修改一下,让它显示的异常信息更详细一点:

@Override
public InputStream getBody() throws IOException
return new ByteArrayInputStream(("fallback( code:" + Integer.toString(this.getRawStatusCode()) + " message:" + this.getStatusText()+")").getBytes());

这里我们将异常码、异常信息全部显示出来,然后重启Zuul,重新访问User的findById服务:

【Spring


我们可以看到异常响应信息修改成功。

三、各路FallBack回顾

既然讲了Zuul的回退机制,不得不提一下之前的几个组件使用Hystrix的回退机制。
1、Ribbon
对于使用Ribbon组件的微服务,在使用Hystrix时,在需要设置退回响应的服务方法上添加@HystrixCommand注解,然后指定fallbackMethod参数指向的方法名即可:

@Component
public class StoreIntegration

@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters)
//do stuff that might fail


public Object defaultStores(Map<String, Object> parameters)
return /* something useful */;

2、Feign
对于使用Feign组件进行声明式服务调用的服务,我们在相应的FeignClient接口的@FeignClient注解的fallback参数中指定其回退类(该退回类是该接口的实现类)即可:

@FeignClient(name = "hello", fallback = HystrixClientFallback.class)
protected interface HystrixClient
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();


static class HystrixClientFallback implements HystrixClient
@Override
public Hello iFailSometimes()
return new Hello("fallback");

亦或是指定fallbackFactory参数,实现一个回退方法工厂类(工厂类的泛型是FeignClient接口):

@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
protected interface HystrixClient
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();


@Component
static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient>
@Override
public HystrixClient create(Throwable cause)
return new HystrixClient()
@Override
public Hello iFailSometimes()
return new Hello("fallback; reason was: " + cause.getMessage());

;

四、总结

这里我们总结一下Zuul的回退机制。实现Zuul的回退,有以下四步:
1、创建一个继承FallbackProvider回退提供器的父类的子类
2、实现FallbackProvider子类的“getRoute”方法,返回值即是代理的服务的路由地址(默认为该微服务在Eureka中的应用名)。
3、实现FallbackProvider子类的“fallbackResponse”方法,根据不同的异常类型,返回不同的异常信息。
4、将该FallbackProvider子类的Bean注入到启动或配置类中。

参考:《51CTO学院Spring Cloud高级视频》

Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul)

Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul)


1、Eureka

Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。

Eureka包含两个组件:Eureka Server和Eureka Client
Eureka Server提供服务注册服务,各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

EurekaClient是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在项目启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

微服务框架中三种角色:

    Eureka Server提供服务注册和发现
    项目服务提供方将自身服务注册到Eureka,从而使服务消费方可以找到
    项目服务消费方从Eureka获取服务列表,从而能够消费服务


配置如下:

eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://$eureka.instance.hostname:$server.port/eureka/        #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。

在项目配置类上加注解:
@EnableEurekaServer  //EurekaServer服务器端配置类,接受其它微服务注册进来

修改页面上显示的不足,需要完善:
(1)主机名称:服务器名称修改
instance-id: microservicecloud-dept8001

server:
  port: 8001
  
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml  #mybatis所在路径
  type-aliases-package: com.atguigu.springcloud.entities #entity别名类
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml #mapper映射文件
    
spring:
   application:
    name: microservicecloud-dept 
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/cloudDB01
    username: root
    password: 123456
    dbcp2:
      min-idle: 5
      initial-size: 5
      max-total: 5
      max-wait-millis: 200
      
eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: microservicecloud-dept8001


(2)微服务info内容详细信息

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

而且还要引入一个插件,用来读取配置文件中的变量(以$为分割符的):

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-resources-plugin</artifactId>
       <configuration>
         <delimiters>
          <delimit>$</delimit>
         </delimiters>
       </configuration>
     </plugin>
info:
  app.name: microservicecloud
  company.name: www.XXXXX.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

Eureka还有自我保护模式
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。

同样,Eureka也可以集群部署。

作为注册中心,Eureka与zookeeper的区别

作为服务注册中心,Eureka比Zookeeper好在哪里????
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。


Zookeeper保证的是CP
Eureka则是AP

    Zookeeper保证CP
    当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

    Eureka保证AP
    Eureka看主要看重了CP所解决不了的问题,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

    Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
    Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
    当网络稳定时,当前实例新的注册信息会被同步到其它节点中

因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。


2、Spring Cloud Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端 负载均衡的工具

1、简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

Ribbon的核心组件:IRule 根据特定算法中从中选取一个要访问的服务
默认的负载均衡算法有:

    RoundRobinRule:轮询
    RandomRule:随机
    AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
    WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule
    RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
    BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
    ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器

 

2、自定义负载均衡算法,在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效,形如:

@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)


要非常注意的是:官方文档明确给出了警告:这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊化定制的目的了。

步骤:
(1) 新建一个包,这个包不要和项目配置类相同:

@Configuration
public class MySelfRule

    @Bean
    public IRule myRule()
      
            return new RandomRule();//Ribbon默认是轮询,现在自定义为随机算法
      


(2) 设置主启动类:

import xx.xxx.xx.MySelfRule;
 
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
public class DeptConsumer_App

  public static void main(String[] args)
  
   SpringApplication.run(DeptConsumer_App.class, args);
  


(3) 启动即可。


3、Feign

官网解释:
http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易,只需要创建一个接口,然后在上面添加注解即可。
参考官网:https://github.com/OpenFeign/feign

1、为什么引入Feign?Feign到底能干什么呢?

Feign旨在使编写Java Http客户端变得更容易。

前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

@FeignClient(value = "MICROSERVICECLOUD-DEPT")
public interface DeptClientService

  @RequestMapping(value = "/dept/get/id",method = RequestMethod.GET)
  public Dept get(@PathVariable("id") long id);
 
  @RequestMapping(value = "/dept/list",method = RequestMethod.GET)
  public List<Dept> list();
 
  @RequestMapping(value = "/dept/add",method = RequestMethod.POST)
  public boolean add(Dept dept);

 

@RestController
public class DeptController_Feign

  @Autowired
  private DeptClientService service = null;
 
  @RequestMapping(value = "/consumer/dept/get/id")
  public Dept get(@PathVariable("id") Long id)
  
   return this.service.get(id);
  
 
  @RequestMapping(value = "/consumer/dept/list")
  public List<Dept> list()
  
   return this.service.list();
  
 
  @RequestMapping(value = "/consumer/dept/add")
  public Object add(Dept dept)
  
   return this.service.add(dept);
  

 

总结:Feign与Ribbon之间的关系

Feign通过接口的方法调用Rest服务(之前是Ribbon+RestTemplate),
该请求发送给Eureka服务器(http://MICROSERVICECLOUD-DEPT/dept/list), 通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。


4、Hystrix

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

Hystrix的主要功能:

    服务降级
    服务熔断
    服务限流
    接近实时的监控


(1)服务降级
整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
一定要注意的一点是:服务降级是在客户端处理的,与服务端没关系。

@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>

  @Override
  public DeptClientService create(Throwable throwable)
  
   return new DeptClientService() 
     @Override
     public Dept get(long id)
     
       return new Dept().setDeptno(id)
               .setDname("该ID:"+id+"没有没有对应的信息")
               .setDb_source("no this database in MySQL");
     
 
     @Override
     public List<Dept> list()
     
       return null;
     
 
     @Override
     public boolean add(Dept dept)
     
       return false;
     
   ;
  


并指定:@FeignClient(value = “MICROSERVICECLOUD-DEPT”,fallbackFactory=DeptClientServiceFallbackFactory.class)

(2)服务熔断
熔断机制是应对雪崩效应的一种微服务链路保护机制。
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。

@RestController
public class DeptController

  @Autowired
  private DeptService service = null;
 
  @RequestMapping(value="/dept/get/id",method=RequestMethod.GET)
    @HystrixCommand(fallbackMethod = "processHystrix_Get")
  public Dept get(@PathVariable("id") Long id)
  
   Dept dept =  this.service.get(id);
   if(null == dept)
   
     throw new RuntimeException("该ID:"+id+"没有没有对应的信息");
   
   return dept;
  
 
  public Dept processHystrix_Get(@PathVariable("id") Long id)
  
   return new Dept().setDeptno(id)
           .setDname("该ID:"+id+"没有没有对应的信息,null--@HystrixCommand")
           .setDb_source("no this database in MySQL");
  

当然需要在主配置类上标注:@EnableCircuitBreaker//对hystrixR熔断机制的支持


(3)服务监控Hystrix Dashboard
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。


5、 Zuul

Zuul包含了对请求的路由和过滤两个最主要的功能
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的项目,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。

注意:Zuul服务最终还是会注册进Eureka

提供=代理+路由+过滤三大功能

主要两大功能:路由和过滤。

以上是关于Spring Cloud总结29.Zuul的FallBack回退机制的主要内容,如果未能解决你的问题,请参考以下文章

spring cloud openFeign传参的一些总结(有错,待更新)

32Spring Cloud 服务跟踪总结

Spring Cloud 与微服务学习总结(18)—— Spring Cloud Gateway 2.0 详解

Spring Cloud 与微服务学习总结(18)—— Spring Cloud Gateway 2.0 详解

Spring Cloud 与微服务学习总结(15)—— Spring Cloud 2021.0.1 发布

总结Spring Cloud各个组件配套使用