Spring Cloud——服务容错保护Hystrix

熔断器,旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。

比如某个小弟故障了,你调用它半天没有响应,你却不知道,一直在等这个响应,这时别的小弟也在调用你的服务,那么当请求多了,就会发生严重的阻塞。这个时候Hystrix就派上用场了,Hystrix发现某个小弟不在状态不稳定立马让它下线,让其它小弟来顶上来,或者给你说不用等了这个小弟今天肯定不行,该干嘛赶紧干嘛去别在这排队了。

借用一下上篇文章:https://blog.csdn.net/hjy132/article/details/84783413 ,服务注册中心、服务提供者以及服务消费者的程序。

  • 启动注册中心eureka服务cloud_eureka_server
  • 启动两个服务cloud_service,端口分别为9881和9882
  • 启动cloud_web工程

在没有加入熔断器之前,关闭9881的服务,发生GET请求http://localhost:9884/cloudweb/helloFang,页面显示如下信息:

Spring Cloud——服务容错保护Hystrix_第1张图片

下面开始引入Spring Cloud Hystrix

(1)在cloud_web工程pom.xml中引入Hystrix依赖


    org.springframework.cloud
    spring-cloud-starter-hystrix

(2)在启动主类中使用注解@EnableCircuitBreaker开启断路器功能

@EnableDiscoveryClient
@EnableCircuitBreaker
@SpringBootApplication
public class CloudWebApplication {

    /*Spring提供的用于访问Rest服务的客户端*/
    @Bean
    @LoadBalanced  //开启客户端负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(CloudWebApplication.class, args);
    }
}

(3)改造服务消费方式,新增CloudWebService类,注入RestTemplate实例,然后将CloudWebController中对RestTemplate的使用迁移到helloFang函数中,并增加@HystrixCommand注解来指定回调方法

@Service
public class CloudWebService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand( fallbackMethod = "helloFallback")
    public String helloFang(){
        ResponseEntity p=restTemplate.getForEntity("http://cloudservice/hello?para={1}",String.class,"hjy");
        return p.getBody();
    }

    public String helloFallback(){
        return "error";
    }
}

(4)修改CloudWebController类

@RestController
public class CloudWebController {

    @Autowired
    private CloudWebService cloudWebService;

    @RequestMapping(value = "/helloFang",method = RequestMethod.GET)
    public String helloFang(){
        return cloudWebService.helloFang();
    }
}

(5)测试

重启刚才关掉9881端口的服务cloud_service,访问http://localhost:9884/cloudweb/helloFang可以轮询两个服务cloudservice,此时关闭9881端口的服务,当轮询到9881端口的服务时,输出以下内容:(不再是之前的错误了,Hystrix服务回调生效)

(6)阻塞测试

下面模拟一下服务阻塞(长时间未响应)的情况,我们对cloud_service的/hello接口做一些修改

@RestController
public class HelloController {

    @Autowired
    private DiscoveryClient client;

    @RequestMapping("hello")String hello(HttpServletRequest request) throws Exception {
        String s=request.getParameter("para");
        ServiceInstance instance=client.getLocalServiceInstance();
        //让处理线程等待几秒钟
        int a=new Random().nextInt(2000);
        System.out.println("睡眠时间:"+a);
        Thread.sleep(a);
        return "host:"+instance.getHost()+"    ServiceId:"+instance.getServiceId()+
                "     port:"+instance.getPort()+"    参数为:"+s+"    睡眠时间:"+a;
    }
}

由于Hystrix默认超时时间为1000ms,所以这里以一定概率发生超时来触发断路器。为了更精准观察断路器触发,在消费者调用函数中做时间记录:

@Service
public class CloudWebService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand( fallbackMethod = "helloFallback")
    public String helloFang(){
        long start=System.currentTimeMillis();
        ResponseEntity p=restTemplate.getForEntity("http://cloudservice/hello?para={1}",String.class,"hjy");
        long end=System.currentTimeMillis();
        System.out.println("消耗时间:"+(end-start));
        return p.getBody()+"     消耗时间:"+(end-start);
    }

    public String helloFallback(){
        return "请求超时";
    }
}

重新启动cloud_service和cloud_web实例,连续访问http://localhost:9884/cloudweb/helloFang几次,发现消耗时间大于1000ms时,就会返回请求超时。

在application.yml中可修改Hystrix的超时时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 8000

 

你可能感兴趣的:(Web开发,Java)