服务降级
8001先从自身找问题:设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback
8001fallback
①业务类启用
修改service
@Service
public class PaymentService {
//成功
public String paymentInfo_OK(Integer id){
return "线程池:"+Thread.currentThread().getName()+" paymentInfo_OK,id: "+id+"\t"+"哈哈哈" ;
}
//失败
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") //3秒钟以内就是正常的业务逻辑
})
public String paymentInfo_TimeOut(Integer id){
int timeNumber = 5;//这里是5s,所以被认为是超时
int x=10/0;
try { TimeUnit.SECONDS.sleep(timeNumber); }catch (Exception e) {e.printStackTrace();}
return "线程池:"+Thread.currentThread().getName()+" paymentInfo_TimeOut,id: "+id+"\t"+"😭"+" 耗时(秒)"+timeNumber;
}
//兜底方法
public String paymentInfo_TimeOutHandler(Integer id){
return "线程池:"+Thread.currentThread().getName()+" 系统繁忙, 请稍候再试 ,id: "+id+"\t"+"哭了哇呜";
}
}
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
②主启动类激活
添加新注解@EnableCircuitBreaker
80fallback
80订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护
①改yml
feign:
hystrix:
enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。
②主启动
@EnableHystrix
③修改Controller
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //1.5秒钟以内就是正常的业务逻辑,但是设置8001执行要3s.所以80必然自我降级
})
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
//兜底方法
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
}
目前问题
1、每个业务方法对应一个兜底的方法,代码膨胀
解决:
@DefaultProperties(defaultFallback = "")
修改controller
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") //全局的
@RestController
@Slf4j
public class OrderHystrixController {
@Resource
private PaymentHystrixService paymentHystrixService;
@Value("${server.port}")
private String serverPort;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
//这个方法是ok的,没有添加 @HystrixCommand,就是用来测试PaymentFallbackService的fall back
public String paymentInfo_OK(@PathVariable("id") Integer id){
String result = paymentHystrixService.paymentInfo_OK(id);
log.info("*******result:"+result);
return result;
}
// ===============================
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand//开启了这个注解,但是没有指明fall back方法,就会用全局的fall back方法
// @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //1.5秒钟以内就是正常的业务逻辑,如果超过了就要调用降级方法
// })
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
//兜底方法
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
}
//下面是全局fallback方法
public String payment_Global_FallbackMethod(){
return "Global异常处理信息,请稍后再试,(┬_┬)";
}
}
2、兜底的方法和业务逻辑混一起,混乱
1、修改cloud-consumer-feign-hystrix-order80
2、根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理
@Component
public class PaymentFallbackService implements PaymentHystrixService {//只要继承的接口中的方法发生了错误,这里就是它们对应的fallback方法
@Override
public String paymentInfo_OK(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_OK , (┬_┬)";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_TimeOut , (┬_┬)";
}
}
3、YML
feign:
hystrix:
enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。
4、PaymentFeignClientService接口
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)//只要该接口的方法出问题了就找PaymentFallbackService
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
测试
@GetMapping("/consumer/payment/hystrix/ok/{id}")
//这个方法是ok的,没有添加 @HystrixCommand,就是用来测试PaymentFallbackService的fall back
public String paymentInfo_OK(@PathVariable("id") Integer id){
String result = paymentHystrixService.paymentInfo_OK(id);
log.info("*******result:"+result);
return result;
}
1、单个eureka先启动7001
2、PaymentHystrixMain8001启动
3、正常访问测试:http://localhost/consumer/payment/hystrix/ok/31
4、故意关闭微服务8001(模拟生产者宕机)
5、此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器。