什么是熔断降级

微服务雪崩效应

当微服务运行不正常,会导致无法正常调用微服务,此时会出现异常,如果这种异常不去处理,可能会导致雪崩效应

微服务的雪崩效应表现在服务与服务之间调用,当其中一个服务无法提供服务时,可能导致其他服务也挂掉。

  • 例如服务C调用服务B,服务B调用服务A,由于服务A异常导致服务B响应缓慢,最终导致服务A和服务B都不可用,而服务B不可用又导致服务C也不可用。
  • 像这样由一个服务所引起的一连串的服务都无法提供服务,就是微服务的雪崩效应
如何解决由于微服务异常所引起的雪崩效应呢?
  • 可以采用熔断、降级的方法去解决
    熔断降级的相同点都是为了解决微服务系统崩溃的问题,但它们是两个不同的技术手段,两者又存在联系
  • 熔断:当下游服务异常时,断开与上游服务的交互。它就相当于保险丝,下游服务异常触发了熔断,从而保证上游服务不受影响
  • 降级:当下游服务异常触发熔断后,上游服务就不再去调用异常的服务,而是执行降级处理逻辑,这个降级处理逻辑可以是本地的一个单独的方法
    而这都是为了保护系统,熔断是当下服务异常时一种保护系统的手段,降级是熔断后上游服务处理熔断的方法。
项目使用Hystrix框架实现熔断、降级处理
  • 开启feign熔断保护
    在feign-dev.yaml中配置
    1
    2
    3
    4
    5
    feign:
    hystrix:
    enabled: true
    circuitbreaker:
    enabled: true
  • 定义降级的两种方式及区别
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.jhj.content.feignclient;

    import com.jhj.content.config.MultipartSupportConfig;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RequestPart;
    import org.springframework.web.multipart.MultipartFile;

    /**
    * @author jhj
    * @version 1.0.0
    * @ClassName MediaServiceClient.java
    * @Description 远程调用媒资服务的接口
    * @createTime 2024年07月06日 16:00:00
    */
    //第一种使用fallback 无法拿到熔断的异常
    //@FeignClient(value = "media-api",configuration = {MultipartSupportConfig.class},fallback = MediaServeceClientFallback.class)
    //第二种拿到熔断的异常信息
    @FeignClient(value = "media-api",configuration = {MultipartSupportConfig.class},fallbackFactory = MediaServeceClientFallbackFactory.class)
    public interface MediaServiceClient {

    @RequestMapping(value = "/media/upload/coursefile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String upload(@RequestPart("filedata") MultipartFile file, @RequestParam(value = "objectName", required = false) String objectName);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.jhj.content.feignclient;

import org.springframework.web.multipart.MultipartFile;

/**
* @author jhj
* @version 1.0.0
* @ClassName MediaServeceClientFallback.java
* @Description fallback 类
* @createTime 2024年07月06日 18:02:00
*/
public class MediaServeceClientFallback implements MediaServiceClient {
@Override
public String upload(MultipartFile file, String objectName) {
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.jhj.content.feignclient;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

/**
* @author jhj
* @version 1.0.0
* @ClassName MediaServeceClientFallbackFactory.java
* @Description fallbackFactory
* @createTime 2024年07月06日 18:03:00
*/
@Slf4j
@Component
public class MediaServeceClientFallbackFactory implements FallbackFactory<MediaServiceClient> {
@Override
public MediaServiceClient create(Throwable cause) {
return new MediaServiceClient() {
//发生熔断执行此方法执行降级流程
@Override
public String upload(MultipartFile file, String objectName) {
log.debug("熔断发生异常:{}",cause.getCause());
return null;
}
};
}
}