目录
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();
}
}
如果同时配置了接口级别的服务降级和内部降级方法,优先走接口级别服务降级