系统整理springCloud系列(七)Hystrix断路器(二)

一,jemeter  配置高并发访问服务端

jemeter使用

系统整理springCloud系列(七)Hystrix断路器(二)

 系统整理springCloud系列(七)Hystrix断路器(二)

系统整理springCloud系列(七)Hystrix断路器(二)

系统整理springCloud系列(七)Hystrix断路器(二)

无延时正常情况下没有问题,延时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;
    }

   

   

}

 

启动客户端

系统整理springCloud系列(七)Hystrix断路器(二)

高并发访问超时服务时,访问原本快的服务时,服务也会卡顿

8001同一层次的其他接口被困死,因为tomcat线程池里面的工作线程已经被挤占完毕 

正因为有上述故障或不佳表现  才有我们的降级/容错/限流等技术诞生

系统整理springCloud系列(七)Hystrix断路器(二)

@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

 

系统整理springCloud系列(七)Hystrix断路器(二)

快速失败,以免压倒整个服务

服务端对超时进行保护

客户端模仿服务端也要快速失败

加入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异常处理信息,请稍后再试,(┬_┬)";
    }

 

此时服务端,和业务逻辑混在一起,代码混乱不易维护

下回解决兜底方法与业务逻辑代码混在一个问题。