总结来说就是如果下游服务挂了,而上游有多个服务去调用他,那么上游的服务就全部挂掉了,这样会造成雪崩效应,从而使服务大面积的失效。
这就需要在连接下游服务超时或者异常时会降级走我们定义的方法。或者在一段时间内失败的比例大于配置,那么熔断器会打开,即使正确调用还是会走降级方法。等过一段时间后会尝试重新调用,如果调用失败,继续熔断,如果成功则可以正常调用。
1.实现
1.修改Application类
修改application中开启Hystrix。
@EnableFeignClients #开启feign @EnableCircuitBreaker #开启Hystrix
2.修改application.yml
修改成以下内容。
feign: hystrix: enabled: true #默认hystrix是不开启的 需要开启 ribbon: ConnectTimeout: 5000 # 请求连接的超时时间 默认的时间为 1 秒 ReadTimeout: 5000 # 请求处理的超时时间 hystrix: command: default: #default全局有效,service id指定应用有效 execution: timeout: #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据 enabled: true isolation: strategy: SEMAPHORE thread: timeoutInMilliseconds: 5000 #断路器超时时间,默认1000ms circuitBreaker: enabled: true requestVolumeThreshold: 10 #默认20 ,熔断的阈值,如何user服务报错满足10次,熔断器就会打开,就算order之后请求正确的数据也不行。 sleepWindowInMilliseconds: 8000 #默认5S , 等5S之后熔断器会处于半开状态,然后下一次请求的正确和错误讲决定熔断器是否真的关闭和是否继续打开 errorThresholdPercentage: 0.5
3.新建UserClientFallBack熔断类
import org.springframework.stereotype.Component; @Component public class UserClientFallBack implements DcClient { @Override public String consumer() { String error= "对不起又是我的错"; System.out.println(error); return error; } @Override public String consumer2() { // TODO Auto-generated method stub return null; } }
依赖于上文 只要在DcClient 加入fallback =UserClientFallBack.class 然后在调用失败之后,会直接返回定义的错误,而不会抛出异常。
4.调用
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "eureka-client",fallback =UserClientFallBack.class ) public interface DcClient { @GetMapping("/aaa/dc?dk=3002") String consumer(); @GetMapping("/aaa/dc?dk=3002") String consumer2(); }
相对于ribbon使用不同的请求类型需要不同的方法 feign,通过接口的参数就可以指定。 如
#post请求 入参为user对象 @PostMapping("/x/x") Result getDept(@RequestBody User user); #get请求 入参为 string @GetMapping("/x/x/{userName}") Result getDept(@PathVariable String userName);
正常调用后。
失败的调用获取是连接超时。