当一个服务端的业务响应的时间过长的时候或者业务处理逻辑处理异常,不应该等待,应该给出一种处理方法
超时导致服务器变慢(转圈) --->超时不再等待
出错(宕机或程序运行出错) --->出错要有兜底
pom文件依赖 :
代码语言:javascript复制 <!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
主启动类需要加注解:
代码语言:javascript复制@EnableHystrix
yml文件设置:
代码语言:javascript复制feign:
hystrix:
enabled: true
feign:hystrix:enabled: true的作用,官网解释“Feign将使用断路器包装所有方法”,也就是将@FeignClient标记的那个service接口下所有的方法进行了hystrix包装(类似于在这些方法上加了一个@HystrixCommand),这些方法会应用一个默认的超时时间为1s
情况1
代码语言:javascript复制 /**
* 超时访问,演示降级
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
})
public String paymentInfo_TimeOut(Integer id)
{
int second = 5;
try { TimeUnit.SECONDS.sleep(second); } catch (InterruptedException e) { e.printStackTrace(); }
return "线程池:" Thread.currentThread().getName() "paymentInfo_TimeOut,id: " id "t" "O(∩_∩)O,耗费秒: " second;
}
public String paymentInfo_TimeOutHandler(Integer id){
return "/(ㄒoㄒ)/调用支付接口超时或异常:t" "t当前线程池名字" Thread.currentThread().getName();
}
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties ={@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="3000") }) @HystrixCommand:需要进行降级处理的业务处理方法的标注注解 fallbackMethod :发生时间过长的时候或运行错误的时候需要调用的方法 @HystrixProperty:相关参数设置,如上就是设置超时时间,超过了3s就调用方法
情况2:每个业务方法对应一个兜底的方法,代码膨胀,统一和自定义的分开
代码语言:javascript复制@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class PaymentHystirxController
{
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand //加了@DefaultProperties属性注解,并且没有写具体方法名字,就用统一全局的
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
{
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
{
return "paymentTimeOutFallbackMethod,对方系统繁忙,请10秒钟后再次尝试/(ㄒoㄒ)/";
}
public String payment_Global_FallbackMethod()
{
return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";
}
}
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") defaultFallback :指定默认改控制类的所有标注了@HystrixCommand的控制方法降级处理都是名字为payment_Global_FallbackMethod 如果需要针对处理的,可以添加fallbackMethod 参数和情况1一样处理掉
情况3:和业务逻辑混一起???混乱
说明:当引发降级处理的时候,也可能是因为服务内部程序发生了错误或调用的服务宕机,这个时候就需要给客户处理的不再是“业务繁忙”而是“内部程序错误”
案列:现在有80服务调用8001端口的业务,但8001端口的服务突然出现宕机;80端口使用feign处理8001端口的调用
代码语言:javascript复制@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",
fallback = PaymentFallbackService.class)
public interface PaymentHystrixService
{
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
代码语言:javascript复制@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackService.class) value:是8001端口的服务名称 fallback :是该接口的实现类,也就是在80端口调用8001端口服务发生错误的时候需要进行的方法
@Component //必须加 //必须加 //必须加
public class PaymentFallbackService implements PaymentHystrixService
{
@Override
public String paymentInfo_OK(Integer id) {
return "服务调用失败,提示来自:cloud-consumer-feign-order80";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "服务调用失败,提示来自:cloud-consumer-feign-order80";
}
}
补充 :
说明:现在有80端口控制类调用了8001端口业务处理类,但在8001端口这个服务也设置了服务降级,假设为5s超时处理,而80这边设置的服务降级为3s超时处理,现在业务响如果超过了3s,那么应该响应的是80端口这边的服务降级处理