spring-cloud断路器之Hystrix

云中志

共 4522字,需浏览 10分钟

 · 2021-08-09

前言

昨天我们分享了spring-cloud基于feign声明式的服务调用,演示了声明式服务调用的基本过程,虽然还有很多内容没有分享,但是现阶段仅考虑基本用法,所以更详细的内容暂时先不展开,等这一轮内容分享结束之后,我们再视情况分享。

今天我们要开始分享另一个spring-cloud核心组件——HsystrixHystrix中文含义豪猪,但是它实际的作用和它的名称却相去甚远,在我们spring-cloud家族中,它的用途就是断路器,也叫熔断器。

正如,电路里面的熔断器一样,spring-cloud中的熔断器也起着同样的作用,有所不同的是,电路中的熔断器是根据电路中的电流大小出发的,而我们的Hystrix是根据服务的超时时间触发的,也就是说如果某一个服务达到了我们设定的超时时间,没有正常返回的话,就会触发我们的断路操作,然后会将短路操作的结果返回。

下面,我们通过一个具体的实例来演示下Hystrix的断路原理。

Hystrix

首先我们需要先创建一个spring-boot项目,然后引入hystrix的核心依赖。这个依赖就加在我们需要熔断操作的服务的依赖中,也就是服务提供者的依赖中。

依赖

下面是hystrix的核心依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

因为我们的服务都有都是基于eureka注册中心调用的,所以我们也需要加入eureka的相关依赖和配置,具体可以参考这几天的demo

配置

这里也是针对服务提供者的配置,在项目入口类上加上@EnableCircuitBreaker注解,即可启用Hystrix熔断器。这样,我们的服务就支持熔断操作了。

@SpringBootApplication
@EnableCircuitBreaker
public class SpringCloudHystrixDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudHystrixDemoApplication.classargs);
    }

}

接口熔断配置

这里设置的接口的配置,只需要在接收上加上@HystrixCommand注解即可启用断路器。

为了方便演示,我们这里生成一个随机睡眠时间,人为模拟超时情形。默认情况下,Hystrix的超时熔断时间为1000ms,即只要超过2000ms未正常响应,我们的超时熔断机制就会被触发,然后执行我们的熔断回调方法。

Hystrix的熔断超时时间是可以设置的,而且其他相关的配置项也有很多,由于篇幅和时间的原因,今天我们就先不展开讲了,后面有机会再来分享。

@RequestMapping("/tetHystrix/{name}")
@HystrixCommand
public Object hystrix(@PathVariable(name = "name") String name) {
    JSONObject jsonObject = new JSONObject();
    try {
        Double v = 3000 * Math.random();
        System.out.println("name: " + name + " 睡眠时间:" + v);
        jsonObject.put("sleep", v.longValue());
        jsonObject.put("name", name);
        jsonObject.put("message""请求成功");
        Thread.sleep(v.longValue());
    } catch (Exception e) {
        System.out.println(e);
    }
    return jsonObject;
}

@HystrixCommand注解是支持指定熔断器回调方法的,也就是熔断触发时调用的方法,如果不指定回调方法的话,默认返回的是500错误,下面是前端页面的返回结果:

后端也有错误抛出,我们可以看到hsystrix timed-out and fallback failed错误提示:

这也就是说如果启用断路器,必须指定回调方法,否则虽然也触发了熔断机制,但对调用方而言并不友好,当然如果你只是需要触发断路器,报错也无所谓,那不指定回调方法也不影响。

指定熔断回调方法也很简单,只需要在注解中指定fallbackMethodd的值即可,它的值就是我们回调方法名称

@HystrixCommand(fallbackMethod = "error")

同时我们需要定义一个名字为error,参数与接口保持一致的熔断回调方法:

public Object error(String name) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message""触发服务熔断机制");
        jsonObject.put("name", name);
        return jsonObject;
    }

回调方法的名字可以根据自己的需要自定义,但是参数必须与接口保持一致,否则会报错:

以上配置完成后,我们的服务提供者就配置好了,下面我们来看下调用方的一些配置。

调用方设置

熔断器其实和调用方没有任何关系,所以也不需要任何配置。但是为了便于我们测试,所以我们专门写了一个测试controller,在controller内部,我们循环调用前面定义的服务提供者。

@RequestMapping("/testHy")
public Object testHystrix() {
    List<JSONObject> jsonObjectList = Lists.newArrayList();
    for (int i = 0; i < 10; i++) {
        jsonObjectList.add(restTemplate.getForObject("http://spring-cloud-Hystrix-demo/tetHystrix/" + i, JSONObject.class));
    }
    return jsonObjectList;
}

测试

测试也很简单,我们先启动服务提供者(加了熔断配置的服务提供者),然后访问我们的/testHy,我们可以看到,在所有请求中,只有4个是成功返回的,其余的都因为超时触发熔断机制。

关于这一点,我们从后台打印的睡眠时间也可以看出来:

前面我们也说了,默认情况下,超时熔断时间为1000ms(有的书上说是3000,可能是版本问题,也有可能是作者搞错了,我实测的结论是1000ms),如果超过这个时间,就会触发熔断机制,执行并返回熔断回调方法。

总结

关于Hystrix今天我们主要通过一个实例演示了它的用法,当然它还有很多内容,但是由于时间的关系,我们今天的内容就先到这里,后续有时间的话,我们再好好刨析Hystrix的实现原理。

好了,今天就到这里吧,大家晚安!

- END -


浏览 29
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报