@HystrixCommand设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback
@HystrixCommand报异常后如何处理,一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
package com.zcl.springcloud.service.Impl;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.zcl.springcloud.service.PaymentService;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* 描述:
*
* @author zhong
* @date 2022-09-19 16:25
*/
@Service
public class PaymentServiceImpl implements PaymentService {
/**
* 正常访问
* @param id
* @return
*/
@Override
public String paymentInfo_OK(Integer id) {
return "线程池:"+Thread.currentThread().getName()+"paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O";
}
/**
* 超时演示,服务降级,超过3秒调用下面指定的方法进行返回
* @param id
* @return
*/
@Override
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandel",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
})
public String paymentInfo_TimeOut(Integer id) {
// int ss = 1 / 0; // 模拟内部代码异常,执行兜底方法
int age = 5;
try { TimeUnit.SECONDS.sleep(age); } catch (InterruptedException e) { e.printStackTrace(); }
return "线程池:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id: "+id+"\t"+"O(∩_∩)O,耗费秒"+age;
}
/**
* 服务容错,兜底方法,当上面的程序报错时执行该方法
* @param id
* @return
*/
public String paymentInfo_TimeOutHandel(Integer id){
return "线程池:"+Thread.currentThread().getName()+"paymentInfo_TimeOutHandel,id: "+id;
}
}
@EnableCircuitBreaker注解到启动类激活http://localhost:8001/payment/hystrix/timeout/100
当浏览器请求转圈圈3秒后就会输出如下
兜底方法,并且后端也会出现sleep interrupted(指定了睡眠5秒)线程睡眠中断报错
线程池:HystrixTimer-1系统繁忙或运行报错,id: 100(ㄒoㄒ)~~
当测试8001内部出现报错的时候也会直接执行兜底方法
80订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护
我们自己配置过的热部署方式对java代码的改动明显,但对@HystrixCommand内属性的修改建议重启微服务
feign:
hystrix:
enabled: true
添加
@EnableHystrix注解完成开启,注解包路径import org.springframework.cloud.netflix.hystrix.EnableHystrix;
在远程调用支付服务时,8001服务的超时时间设置5秒后执行服务降级,而当前的80服务的超时时间最多是1.5秒,而8001服务默认线程睡眠3秒,所以80等待不到支付信息就会给自己进行服务降级
项目重启后通过:http://localhost/consumer/payment/hystrix/timeout/100进行访问测试
/**
* 远程调用微服务睡眠三秒的接口,超时1.5秒后调用服务降级方法
* @param id
* @return
*/
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
{
// int age = 1 / 0; // 自测服务降级
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
/**
* 服务熔断方法
* @param id
* @return
*/
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
{
return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";
}
可以通过定义全局的服务降级方法,如果没有指定具体的一对一降级方法就使用默认的
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")指定全局的服务降级方法@HystrixCommand注解,需要将原来的去掉,避免重复package com.zcl.springcloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.zcl.springcloud.service.PaymentHystrixService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 描述:消费者调用提供者控制器
*
* @author zhong
* @date 2022-09-19 19:27
*/
@Slf4j
@RestController
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystirxController {
/**
* 注入Feign业务接口
*/
@Resource
private PaymentHystrixService paymentHystrixService;
/**
* 定义全局服务降级方法
* @return
*/
private String payment_Global_FallbackMethod(){
return "Global xxx对方系统繁忙或者已宕机,请10秒后在次尝试...";
}
/**
* 远程调用微服务睡眠三秒的接口,超时1.5秒后调用服务降级方法
* @param id
* @return
*/
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
/*@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})*/
@HystrixCommand
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
{
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
/**
* 服务熔断方法
* @param id
* @return
*/
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
{
return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";
}
}
通过访问:http://localhost/consumer/payment/hystrix/timeout/100测试
既让需要使用到Feign进行远程调用,就必须有接口,我们可以在接口上进行服务降级操作,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦
服务降级,客户端去调用服务端,碰上服务端宕机或关闭
在原来的控制器里面的服务降级方法都写在了一起,导致代码的耦合度高,也不利于美观,下面就是为了对上提出的问题做一个优化处理
根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处(实现类必须要添加
@Component注解添加到Spring容器中)
package com.zcl.springcloud.service;
import org.springframework.stereotype.Component;
/**
* 描述:接口实现类
*
* @author zhong
* @date 2022-09-19 21:47
*/
@Component
public class PaymentFallbackService implements PaymentHystrixService{
@Override
public String paymentInfo_OK(Integer id) {
return "-----PaymentFallbackService fallback paymentInfo_OK,(ㄒoㄒ)~~";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "-----PaymentFallbackService fallback paymentInfo_TimeOut,(ㄒoㄒ)~~";
}
}
feign:
hystrix:
enabled: true # 开启支持服务降级
fallback必须要开启调用
fallback = PaymentFallbackService.class才能为每一个接口提供
package com.zcl.springcloud.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 描述:调用微服务接口
*
* @author zhong
* @date 2022-09-19 19:24
*/
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
xxxx
}
启动7001Eureka服务注册中心
启动8001服务提供者
正常的访问测试:http://localhost/consumer/payment/hystrix/ok/
故障关闭微服务8001
客户端自己调用提示
此时服务端provider已经宕机了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器