SpringCloud 2020.0.4 系列之服务降级

1. 概述

老话说的好:做人要正直,做事要正派,胸怀坦荡、光明磊落,才会赢得他人的信赖与尊敬。

 

言归正传,之前聊了服务间通信的组件 Feign,今天我们来聊聊服务降级。

服务降级简单的理解就是给一个备选方案,当服务调用报错或者超时时,能终止远程调用,并很快的返回备选的结果,避免引发服务雪崩。

 

今天我们用两个例子,模拟一下 接口报错 和 接口超时 的服务降级实现。

我们使用 hystrix 实现服务降级,虽然从 Spring Cloud 2020.0 版本开始,移除了 hystrix 组件,但并不影响我们对他的使用。

闲话不多说,直接上代码。

 

2. 接口报错的服务降级

2.1 被调用服务

2.1.1 接口代码

    @GetMapping("/exception")
    String exception() throws Exception;

 

2.1.2 实现类代码

    @Override
    public String exception() throws Exception {
        if(1==1) {
            throw new Exception("模拟异常");
        }
        return null;
    }

 

2.2 调用服务

2.2.1 主要依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 健康检查 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.9.RELEASE</version>
        </dependency>

这里 hystrix 使用目前的最新版本 2.2.9.RELEASE。

 

2.2.2 主要配置

feign:
  circuitbreaker:
    enabled: true   # 开启 feign 的断路器

hystrix:
  command:
    default:
      fallback:
        enabled: true     # 开启服务降级

 

2.2.3 降级工厂类的开发

@Component
public class MyEurekaClientServiceFactory implements FallbackFactory<EurekaClientService> {
    @Override
    public EurekaClientService create(Throwable cause) {

        return new EurekaClientService() {
            
            @Override
            public String exception() throws Exception {
                System.out.println("exception方法 降级");
                return "exception方法 降级";
            }
        };
    }
}

 

2.2.4 在 Feign 接口配置降级工厂类

@FeignClient(name = "my-eureka-client", fallbackFactory = MyEurekaClientServiceFactory.class)  // name为 调用服务的名称
@RequestMapping("/api")
public interface EurekaClientService {

    @GetMapping("/exception")
    String exception() throws Exception;

}

 

2.2.5 启动类增加 @EnableHystrix 注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class MyFeignApplication {

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

 

2.2.6 启动服务测试

可以正常进入降级方法。

 

3. 接口超时的服务降级

3.1 被调用服务

3.1.1 接口代码

    @GetMapping("/timeout")
    String timeout(@RequestParam Integer timeoutSecond);

 

3.1.2 实现类代码

    @Override
    public String timeout(Integer timeoutSecond) {
        System.out.println("调用timeout方法");
        try {
            Thread.sleep(timeoutSecond * 1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "success:" + port;
    }

 

3.2 调用服务

3.2.1 主要配置

feign:
  client:
    config:
      # 全局配置
      default:
        connectTimeout: 1000   # 连接超时时间,单位ms
        readTimeout: 3000         # 获取Response响应超时时间,单位ms

      # 针对 my-eureka-client 的 feign 配置,优先级高于全局配置
      my-eureka-client:
        connectTimeout: 300   # 连接超时时间,单位ms
        readTimeout: 5000         # 获取Response响应超时时间,单位ms
  circuitbreaker:
    enabled: true   # 开启 feign 的断路器


hystrix:
  command:
    default:
      fallback:
        enabled: true     # 开启服务降级
      execution:
        timeout:
          enabled: true   # 全局超时配置
        isolation:
          thread:
            timeoutInMilliseconds: 3000    # 超时时间配置
            interruptOnTimeout: true       # 超时后是否终止线程
            interruptOnFutureCancel: true  # 取消后是否终止线程

注意:feign 的 readTimeout 属性和 hystrix 的 timeoutInMilliseconds 属性会同时生效,以超时时间最短的为准。

 

3.2.2 降级工厂类的开发

@Component
public class MyEurekaClientServiceFactory implements FallbackFactory<EurekaClientService> {
    @Override
    public EurekaClientService create(Throwable cause) {

        return new EurekaClientService() {
            
            @Override
            public String exception() throws Exception {
                System.out.println("exception方法 降级");
                return "exception方法 降级";
            }

            @Override
            public String timeout(Integer timeoutSecond) {
                return "timeout方法 降级";
            }
        };
    }
}

 

3.2.3 启动服务测试

可以正常进入降级方法。

 

4. 综述

今天聊了一下 服务降级 的相关知识,希望可以对大家的工作有所帮助。

欢迎帮忙点赞、评论、转发、加关注 :)

关注追风人聊Java,每天更新Java干货。

 

5. 个人公众号

追风人聊Java,欢迎大家关注