首页 > 其他分享 >Hystrix服务降级fallback

Hystrix服务降级fallback

时间:2023-03-08 16:34:02浏览次数:37  
标签:降级 服务 Hystrix 代码 熔断 fallback 方法

Hystrix服务降级fallback

 

通过前面章节的讲解,我们都知道当服务熔断被触发之后,我们再次访问会返回如下结果:

这样的响应结果,提供给用户显然是不够友好的。上面的提示信息有两层含义:

  • 服务熔断被触发,也就是断路器处于开启状态
  • 断路器被触发之后,访问fallback方法,但是这个fallback方法我们之前没有定义

当服务提供者故障触发熔断机制,此时你需要预先提供一个处理方法,作为降级后的执行方法一般叫fallback,fallback方法返回值一般是设置的默认值或者来自缓存,或者是一些友好提示信息。

一、服务降级发生的条件?

满足下列条件任何一个异常条件,都会产生服务降级

  • 被访问的服务接口达到熔断标准(SHORT_CIRCUITED)
  • 被访问的服务接口代码抛出异常(FAILURE)
  • 被访问的服务接口响应超时(TimeOut)
  • hystrix线程池或信号量爆满(THREAD_POOL_REJECTED 或SEMAPHORE_REJECTED )
Failure TypeException classException.causesubject to fallback
FAILURE HystrixRuntimeException underlying exception (user-controlled) YES
TIMEOUT HystrixRuntimeException j.u.c.TimeoutException YES
SHORT_CIRCUITED HystrixRuntimeException j.l.RuntimeException YES
THREAD_POOL_REJECTED HystrixRuntimeException j.u.c.RejectedExecutionException YES
SEMAPHORE_REJECTED HystrixRuntimeException j.l.RuntimeException YES

所以我们可以认为:服务降级实际上也是“异常处理”的一种方式,处理的是上面的5种异常。

二、在控制层实现服务降级(方法级别)

在上一节服务熔断的代码的基础上加上服务降级方法配置

  • @HystrixCommand注解加上属性fallbackMethod属性
    • 当捕获到任何一种服务降级的异常类型的时候,表示原函数(pwdreset)已经无法正确响应结果,执行fallback函数(pwdresetFallback)。
  • 增加fallbackMethod对应的函数,返回值要与原函数一致。

**(重要)**为什么在控制层实现服务降级?

  1. 在实际的生产代码中,一种比较好的异常处理机制是:将服务层、持久层代码等所有底层代码抛出的异常转换为自定义异常不断的向上抛出,最后由控制层处理或者由Spring 全局异常处理。从而避免异常在底层被处理,上层无感应。可能造成一种现象:用户进行了一个操作,操作界面没有任何反应,但是后台服务报错了。
  2. 服务降级也是通过异常抛出及捕获实现的,所以一般不要在服务层和持久层等底层服务方法上进行hystrix配置。相当于把异常在底层处理了,造成上层无感应。

此时在服务熔断之后(或者其他的服务降级条件满足之后),我们再次访问“/sysuser/pwd/reset”接口。结果如下,说明执行了本地fallback方法。

三、Hystrix类级别的配置(笔者推荐)

第二小节中这种方法级别的服务降级配置方式的缺点十分的明显:那就是我们需要针对方法级别进行服务熔断和服务降级的配置;不只是配置,我们还需要针对每一个方法写fallback方法,无疑很大程度上增加了我们的代码量。那么有没有一种可以全局实现服务降级的配置方式呢?就是下面要为大家介绍的:

@DefaultProperties(defaultFallback = "commonFallbackMethod")

  • @DefaultProperties是一个类方法级别的注解
  • defaultFallback 可以指定该类中所有方法在发生服务降级的时候,执行的本地fallback函数。
  • 需要我们在一个类中定义一个fallback函数,如:commonFallbackMethod
  public AjaxResponse commonFallbackMethod() {
    return AjaxResponse.error(CustomExceptionType.SYSTEM_ERROR,
            "系统繁忙,请稍后再试!");
  }

最后在需要进行服务降级后执行fallback的方法的方法上面加上

@HystrixCommand

这样我们实现服务降级的代码就减少了很多,但是仍然存在一个问题让开发者不爽:我们需要在每一个类里面写一个commonFallbackMethod函数,为了降低fallback函数与实际Controller业务处理类的耦合,进一步减少代码的冗余,我们通常是可以定义一个BaseController,然后让其他的Controller类来继承。

public class BaseController {
       //通用hystrix回退方法
      public AjaxResponse commonFallbackMethod() {
        return AjaxResponse.error(CustomExceptionType.SYSTEM_ERROR,
            "系统繁忙,请稍后再试!");
      }
}

Hystrix结合Feign服务降级

 

通过前面几个小节的说明,对于服务降级目前有两种方式:

  • 使用DefaultProperties注解在类级别的代码上进行服务降级,这种方法一定程度上减少了很多冗余代码。但是通用fallback方法仍然与实际业务的处理方法耦合在一个类中,可以通过BaseController的方式解决。笔者较为推荐这种方式
  • 使用HystrixCommand注解的CommandProperties配置,在方法级别实现服务降级。这种方法代码十分冗余,需要针对每一个方法做配置,写fallback。最好用于一些重点业务的个性化接口。
  • 用一句话总结就是:追求统一处理、允许个性化实现

下面为大家介绍服务降级的另一类方法:在FeignClient上实现服务降级。为什么我称它是另一类方法,而不是另一种方法?因为FeignClient上实现服务降级与上面两种方法的思考的角度是不同的:

  • FeignClient上实现服务降级,从服务调用者的角度考虑:如果服务提供者出现连接超时、服务宕机等问题,作为服务调用者我该如何快速的对服务提供者的接口进行降级,避免造成服务调用者自己的崩溃。
  • HystrixCommand实现服务降级,从服务提供者角度考虑:如果有服务调用者调用我的服务,并且我自己的代码或者触发熔断降级规则后,我该如何快速的告知服务调用者,避免造成服务调用者崩溃。

一、在FeignClient上实现服务降级

  • 首先还是要将Hystrix集成到Spring Cloud服务中,参考《Hystrix集成并实现服务熔断》得第三小节:微服务集成Hystrix
  • 在服务配置文件中打开feign结合hystrix的开关
feign:
  hystrix:
    enabled: true

在FeignClient注解增加fallback处理实现类,如:SmsServiceFallback。

@FeignClient(name="ASERVICE-SMS",fallback = SmsServiceFallback.class)
public interface SmsService {

  @PostMapping(value = "/sms/send")
  AjaxResponse send(@RequestParam("phoneNo") String phoneNo,
                    @RequestParam("content") String content);

}

书写SmsServiceFallback代码,该类要实现FeignClient注解的接口函数。当使用Feign客户端远程调用SmsService .send方法,如果远程服务不可达(网络不可达或宕机),就会执行SmsServiceFallback.send方法作为fallback。

@Component
public class SmsServiceFallback implements SmsService {

   @Override
   public AjaxResponse send(String phoneNo, String content) {
      return AjaxResponse.error(CustomExceptionType.SYSTEM_ERROR
                  ,"短信发送接口失败!");
   }
}

  • 优点:将fallback服务降级方法与实际的业务处理方法分离,耦合度降低,从这个角度来说对程序员比较友好。
  • 缺点:FeignClient注解的接口有多个方法,实现类就要写多个fallback,所以代码冗余量仍然非常大。这个缺点在我看来似乎无关紧要了,因为接口函数定义实际根本就不用我们写,通过IDE一个回车就可以搞定。接口函数的实现内容通过提取公共代码方式就可以搞定。虽然代码行数可能仍然较多,但是独立整齐规范。

标签:降级,服务,Hystrix,代码,熔断,fallback,方法
From: https://www.cnblogs.com/nextgg/p/17192501.html

相关文章

  • 【feign】feign 使用 FallbackFactory<T>获取异常信息,但接口无法注入
    Acomponentrequiredabeanoftype‘XXXService‘thatcouldnotbefound背景:@EnableFeignClients注入问题这是一个多模块cloud工程,其中有一个微服务模块,我在借......
  • hystrix学习(一)之Command Properties之Execution
        一、HystrixCommand.run执行时会用到isolation.strategy:有两个选项二选一:1、线程:在单独的线程上执行,并发请求受线程池中线程数的限制2、信号量:在......
  • 【Sentinel】隔离和降级
    目录​​1.FeignClient整合Sentinel​​​​1.1.修改配置,开启sentinel功能​​​​1.2.编写失败降级逻辑​​​​1.3.总结​​​​2.线程隔离(舱壁模式)​​​​2.1.线程隔离......
  • Springcloud~openfeign开启hystrix基于线程池熔断的传值问题
    我们都知道,在hystrix默认情况下,采用线程池的熔断方式,每个openfeign都有自己的线程,而这使得它无法获取主线程上的变量;现在有个现实的问题就是,当前端登录后,把token经过gatewa......
  • Hystrix核⼼源码剖析
    springboot装配、⾯向切⾯编程、RxJava响应式编程的知识等等,我们剖析下主体脉络。 分析⼊⼝:@EnableCircuitBreaker注解激活了熔断功能,那么该注解就是Hystrix源码追踪的......
  • Feign远程调用结合fallback(Springboot包扫描)
    Feign远程调用结合fallback(Springboot包扫描)微服务项目中,各微服务模块间互相调用,通常使用HTTP协议调用,为了优雅和快速调用服务,通常使用HTTP客户端,如Feign为各服务编写......
  • 面试官:熔断和降级有什么区别?
    熔断和降级都是系统自我保护的一种机制,但二者又有所不同,它们的区别主要体现在以下几点:概念不同触发条件不同归属关系不同1.概念不同1.1熔断概念“熔断”一词早期......
  • Hystrix + OpenFeign+ SpringCloud +Nacos
      注意:2023年2月 springcloud最新版本不支持nacos2.2和hystrix,测试发现以下这个版本还支持<groupId>org.springframework.cloud</groupI......
  • Hystrix Dashboard界面中jQuery报错Uncaught: TypeError: e.indexOf is not a functio
    1、问题描述  在使用SpringCloud整合HystrixDashboard组件监控Hystrix时控制台出现jQuery报错Uncaught:TypeError:e.indexOfisnotafunction,并且监控界面一直load......
  • Hystrix Dashboard
    文章目录​​1、什么是HystrixDashboard?​​​​2、HystrixDashboard(仪表盘)实现​​​​2.1在项目中引入依赖​​​​2.2入口类中开启hystrixdashboard​​​​2.3......