系统整理springCloud系列(七)Hystrix断路器(二)
一,jemeter 配置高并发访问服务端
jemeter使用
无延时正常情况下没有问题,延时5秒的情况下
导致服务卡住转圈
上面还只是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80体验不好,服务端8001直接被拖死 。
二,模拟客户端访问服务端
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {
/**
* 正常访问
*
* @param id
* @return
*/
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfo_OK(@PathVariable("id") Integer id);
/**
* 超时访问
*
* @param id
* @return
*/
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfo_TimeOut(@PathVariable("id") Integer id);
@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}")
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(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //3秒钟以内就是正常的业务逻辑
// })
// @HystrixCommand //不加@HystrixCommand 不使用服务降级; 加了@HystrixCommand 使用服务降级,若有@DefaultProperties,则使用DefaultProperties中的全局方法;加了@HystrixCommand和fallbackMethod, 则使用其中fallbackMethod中的方法
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
}
}
启动客户端
高并发访问超时服务时,访问原本快的服务时,服务也会卡顿
8001同一层次的其他接口被困死,因为tomcat线程池里面的工作线程已经被挤占完毕
正因为有上述故障或不佳表现 才有我们的降级/容错/限流等技术诞生
@HystrixCommand 服务降级注解
先从服务端8001找问题
服务端超时
设置自身调用超时时间的峰值,峰值内可以正常运行, 超过了需要有兜底的方法处理,做服务降级fallback
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") //3秒钟以内就是正常的业务逻辑
})
//兜底方法
public String paymentInfo_TimeOutHandler(Integer id){
return "线程池:"+Thread.currentThread().getName()+" paymentInfo_TimeOutHandler系统繁忙, 请稍候再试 ,id: "+id+"\t"+"哭了哇呜";
}
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbckMethod调用类中的指定方法
主启动类加入@EnableCircuitBreaker
快速失败,以免压倒整个服务
服务端对超时进行保护
客户端模仿服务端也要快速失败
加入pom
<!--新增hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
server:
port: 80
eureka:
client:
register-with-eureka: false
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
feign:
hystrix:
enabled: true
主启动类加入@EnableHystrix
控制器修改
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //3秒钟以内就是正常的业务逻辑
})
// @HystrixCommand //不加@HystrixCommand 不使用服务降级; 加了@HystrixCommand 使用服务降级,若有@DefaultProperties,则使用DefaultProperties中的全局方法;加了@HystrixCommand和fallbackMethod, 则使用其中fallbackMethod中的方法
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异常处理信息,请稍后再试,(┬_┬)";
}
此时又出现另一个问题
如果每一个方法都建一个兜底的方法,造成方法臃肿不好维护
加一个同意默认全局的兜底方法
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") //全局的
//下面是全局fallback方法
public String payment_Global_FallbackMethod(){
return "Global异常处理信息,请稍后再试,(┬_┬)";
}
此时服务端,和业务逻辑混在一起,代码混乱不易维护
下回解决兜底方法与业务逻辑代码混在一个问题。