目录

1、Eureka

2、Feign

2.1、Feign的get请求

2.2、Feign的post请求

3、Hystrix

3.1、熔断降级常见报错

3.2、内部降级方法

3.3、修改服务降级超时时间

3.4、接口级别服务降级

3.5、接口级别服务降级修改超时时间


 

1、Eureka

Eureka客户端注册有两种

@EnableDiscoveryClient 和 @EnableEurekaClient,第一种为通用发现服务,注册中心可以是zk、eureka、consul等,第二种只能是EurekaServer,如果使用的是EurekaServer,不管用这两种注解效果都是一样的,并且要制定客户端的依赖,比如:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

如果使用 @EnableDiscoveryClient 也可以指定第三方客户端依赖,不一样的是,如果使用@EnableEurekaClient,不指定依赖会编译报错,而使用 @EnableDiscoveryClient 不指定依赖,不会编译报错,但是会导致服务注册失败

2、Feign

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

feign接口

@FeignClient(value = "demoFeign")
public interface DemoFeign {

    @RequestMapping(value = "/test1")
    String sayHiFromClientOne();
}

启动器注解:@EnableFeignClients

调用feign接口

@RestController
public class DemoController {

    @Autowired
    DemoFeign demoFeign;

    @RequestMapping(value = "/demo")
    public String test() {
        String result = demoFeign.sayHiFromClientOne();
        System.out.println(result);
        return "DemoController";
    }
}

2.1、Feign的get请求

如果feign使用get方式调用,入参需要加 @RequestParam,否则会直接进入熔断器

@FeignClient(value = "demoFeign", fallback = ErrorFallback.class)
public interface DemoFeign {

    @RequestMapping(value = "/test1", method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam String isHystrix);
}

或者

@FeignClient(value = "demoFeign", fallback = ErrorFallback.class)
public interface DemoFeign {

    @GetMapping(value = "/test1")
    String sayHiFromClientOne(@RequestParam String isHystrix);
}

2.2、Feign的post请求

如果feign使用post方式调用,入参需要加 @RequestBody,否则会直接进入熔断器

@FeignClient(value = "demoFeign", fallback = ErrorFallback.class)
public interface DemoFeign {

    @PostMapping(value = "/test1")
    String sayHiFromClientOne(@RequestBody TestBean bean);
}

3、Hystrix

依赖:在Feign中使用Hystrix,不添加依赖启动会报错

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

3.1、熔断降级常见报错

服务还没注册成功:com.netflix.client.ClientException: Load balancer does not have available server for client

内部降级方法的方法签名跟原方法不相同:fallback method wasn't found

没有配置内部降级方法:com.netflix.hystrix.exception.HystrixRuntimeException: test timed-out and fallback failed

Ribbon负载均衡超时:nested exception is feign.RetryableException: Read timed out executing

3.2、内部降级方法

默认熔断超时时间是1000ms,所以这里延迟2000ms后会进入到降级方法中(无需加@EnableHystrix注解和feign.hystrix.enable配置),且内部降级方法的方法签名跟原方法需要相同,否在会报错 fallback method wasn't found

@RestController
public class TestController {

    @HystrixCommand(fallbackMethod = "fallBack")
    @PostMapping(value = "/test1")
    public String test(@RequestBody TestBean bean) throws Exception {
        System.out.println("进入调用方法");
        Thread.sleep(2000);
        if ("false".equals(bean.getIsHystrix())) {
            throw new Exception("进入Hystrix异常");
        }
        return "TestController:"+bean.getIsHystrix();
    }

    public String fallBack(TestBean bean) {
        return "fallBack Method";
    }
}

不过需要注意的是,这里因为是通过feign来调用的,所以还会有一个ribbon负载均衡的超时时间默认1000ms,所以如果要降级方法生效,需要先放开这个超时时间

ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 60000

如果是负载均衡超时,则报错:nested exception is feign.RetryableException: Read timed out executing

3.3、修改服务降级超时时间

@RestController
public class TestController {

    @HystrixCommand(fallbackMethod = "fallBack",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
            })
    @PostMapping(value = "/test1")
    public String test(@RequestBody TestBean bean) throws Exception {
        System.out.println("进入调用方法");
        Thread.sleep(2000);
        if ("false".equals(bean.getIsHystrix())) {
            throw new Exception("进入Hystrix异常");
        }
        return "TestController:" + bean.getIsHystrix();
    }

    private String fallBack(TestBean bean) {
        return "fallBack Method";
    }
}

3.4、接口级别服务降级

@FeignClient(value = "demoFeign", fallback = ErrorFallback.class)
public interface DemoFeign {

    @PostMapping(value = "/test1")
    String sayHiFromClientOne(@RequestBody TestBean bean);
}

@Component
public class ErrorFallback implements DemoFeign {
    @Override
    public String sayHiFromClientOne(TestBean bean) {
        return "fallBack";
    }
}

@RestController
public class TestController {
    
    @PostMapping(value = "/test1")
    public String test(@RequestBody TestBean bean) throws Exception {
        System.out.println("进入调用方法");
        Thread.sleep(2000);
        if ("false".equals(bean.getIsHystrix())) {
            throw new Exception("进入Hystrix异常");
        }
        return "TestController:" + bean.getIsHystrix();
    }
}

如果需要启动接口级别服务降级,需要配置

feign:
  hystrix:
    enabled: true

3.5、接口级别服务降级修改超时时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000

添加 @HystrixCommand 注解

@RestController
public class TestController {

    @HystrixCommand
    @PostMapping(value = "/test1")
    public String test(@RequestBody TestBean bean) throws Exception {
        System.out.println("进入调用方法");
        Thread.sleep(2000);
        if ("false".equals(bean.getIsHystrix())) {
            throw new Exception("进入Hystrix异常");
        }
        return "TestController:" + bean.getIsHystrix();
    }
}

如果同时配置了接口级别的服务降级和内部降级方法,优先走接口级别服务降级