专栏首页Java学习录服务容错Hystrix

服务容错Hystrix

Hystrix是一个实现断路器模式的库。什么是断路器模式呢?就像我们家庭中的电闸一样,如果有那一处出现意外,那么电闸就会立刻跳闸来防止因为这一处意外而引起更大的事故,直到我们确认处理完那一处意外后才可以再打开电闸。而Hystrix的存在就是为了预防程序中出现这种问题而导致程序不可用的情况。

比如说我们有三个微服务 A、B、C,其中A依赖于B,B依赖于C,如果这时候C出现了问题,那么就导致B不可用,紧接着A也不可用,更有可能导致整个系统不可用。我们接下来就来看看如何利用Hystrix预防这种情况

创建项目 首先我们复制一份cloud-demo-consumer项目,改名为cloud-demo-consumer-hystrix

引入Hystrix的依赖

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
`

application.xml不用变

spring:
  application:
    name: consumer-demo-hystrix
server:
  port: 8090
eureka:
  client:
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: http://root:root@localhost:8761/eureka
  instance:
    prefer-ip-address: true

CloudDemoConsumerApplication改名为CloudDemoConsumerHystrixApplication,并且它的注解应该是

@SpringBootApplication @EnableEurekaClient @EnableCircuitBreake 上方我们不认识的这个@EnableCircuitBreake注解就是表示开启断路器模式的注解

然后我们看一下controller

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/getUser/{id}")
    @HystrixCommand(fallbackMethod = "getUserFallback")
    public User getUser(@PathVariable Long id){
         return restTemplate.getForObject("http://provider-demo/user/getUser/"+id,User.class);
    }
    public User getUserFallback(Long id) {
        User user = new User();
        user.setName("王五");
        return user;
    }
}

它相比较于原先的controller仅仅是多了一个@HystrixCommand(fallbackMethod = “getUserFallback”)注解和一个方法,这个注解呢就是指定Hystrix在此方法超时时调用的方法。

测试 首先启动我们代表Eureka服务的项目,然后启动cloud-demo-provider项目,紧接着启动我们现在的项目。

项目启动以后我们打开浏览器访问localhost:8088/user/getUser/2的时候发现一切正常,网页上返回了张三这个用户。如果我们没有引入Hystrix的时候如果这时候把服务提供者停掉的话在访问会出现什么情况呢,是不是会报错,或者超时呀。

但是现在不一样了,我们引入了Hystrix,所以我们现在停掉提供者访问的时候会发现程序走了注解指定的fallbackMethod,也就是方法getUserFallBack,这个时候我们浏览器得到的结果是王五。

Hystrix默认的超时时间是1秒,也就是说它在等待服务提供者1秒后如果得不到结果的话就会认为提供者挂了,紧接着调用fallbackMethod。

这个时间其实我们可以控制,只需要在yml文件中配置一个属性就可以自定义这个时间

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 1000 #1000毫秒

Feign的支持 接下来我们看一下Feign是怎么使用Hystrix,

这次我们改造cloud-demo-consumer-feign项目,项目名称改为cloud-demo-consumer-feign-hystrix,同样向上述 方式一样引入Hystrix的依赖,

接着 CloudDemoConsumerFeignApplication类名改为 CloudDemoConsumerFeignHystrixApplication,同样的加入@EnableCircuitBreaker注解

有一点不一样的地方是我们需要在yml文件中配置一下来开启Hystrix

feign.hystrix.enabled: true

这里controller中需要改造的不再是指定单个方法,而是指定接口的实现类

@FeignClient(name = "provider-demo", fallback = HystrixClientFallback.class) 来看一下这个实现类

@Component
public class HystrixClientFallback implements UserFeignClient {
    @Override
    public User getUser(Long id) {
        User user = new User();
        user.setName("王五");
        return user;
    }
}

这样的话如果接口中有多个方法的话我们就不必为每一个方法取指定了。

现在我们已经解决了服务提供者挂掉的事情了,但是有点不好的是,我们现在还不能知道服务提供者到底是咋挂的,要是能捕获到服务提供者

抛的异常就好了,其实Hystrix对这个是支持的,我们接下来看一下

fallbackFactory

UserFeignClient上方的注解需要变一下

@FeignClient(name = "provider-demo", fallbackFactory = HystrixClientFactory.class) 这次使用的是fallbackFactory这个属性,我们看一下它指定的这个类又是怎么实现的呢

@Component
public class HystrixClientFactory implements FallbackFactory<UserFeignClient> {
    private static final Logger LOGGER = LoggerFactory.getLogger(HystrixClientFactory.class);
    @Override
    public UserFeignClient create(Throwable cause) {
        HystrixClientFactory.LOGGER.info("the provider error is: {}", cause.getMessage());
        return new UserFeignClient() {
            @Override
            public User getUser(Long id) {
                User user = new User();
                user.setName("王五");
                return user;
            }
        };
    }
}

我们可以看到,在这个create的工厂方法中,它的入参就是服务提供者的异常,得到了这个异常以后才会去做实现。这样是不是更加灵活了呢? 点赞收藏转发好看再走呗!

本文分享自微信公众号 - Java学习录(Javaxuexilu),作者:Java学习录

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 路由器和过滤器-Zuul

    假如现在我们具有四个微服务,分别是用户、订单、支付、催收微服务,它们的调用方式分别是使用http、restful、thrift、kafka。这个时候如果我们在客...

    Java学习录
  • Drools规则引擎入门指南(一)

    Drools的规则文件是以*.drl结尾的文件,我们来看一个最简单的规则文件中都是包含什么。

    Java学习录
  • MySQL索引失效及使用索引的优缺点

    由以下三张图的key_len字段我们可以得出三个索引的长度分别为:title长303,author长122,price长5.

    Java学习录
  • 关于机器学习,这可能是目前最全面最无痛的入门路径和资源!

    之前搞机器学习的那帮人都喜欢用Python,所以Python慢慢就积攒了很多优秀的机器学习库,所谓的库,你就理解为别人封装好的一些具有某些功能的模块,我们可以通...

    企鹅号小编
  • 知晓云公测招募!让你的小程序开发时间,至少缩短 50%

    「知晓云」cloud.minapp.com,是国内第一个专注于微信小程序开发的 BaaS(Backend as a Service)产品,它可以让开发者更快、更...

    知晓君
  • 玩腻了传纸条、漂流瓶,就用它来跟网友分享「小卡片」吧

    今天,知晓程序(微信号 zxcx0101)就为你推荐一款有毒的小程序「一起 Up」,在里面,你不仅可以看到其他用户分享的有趣、有内涵的内容,还能将自己的私货与其...

    知晓君
  • 代码缩进,Tab还是空格?

    Qt君
  • (干货) |机器视觉不可不知的相机内部工作原理

    工业相机是机器视觉系统中的一个关键组件,其最本质的功能就是将光信号转变成有序的电信号。选择合适的相机也是机器视觉系统设计中的重要环节,相机的选择不仅直接决定所采...

    智能算法
  • 机器视觉(第4期)----工业相机综述及接口介绍

    上期我们一起学习了镜头的相关知识,戳下链接: 机器视觉(第3期)----图像采集之镜头原理详述 这期我们一起学习相机和接口的相关知识,工业相机是机器视觉系统中的...

    智能算法
  • Selenium 系列篇(四):JS 篇

    前面 3 篇文章讲了 Selenium 的一些基本操作,利用这部分技能,大部分网站的自动化都能顺利完成。

    AirPython

扫码关注云+社区

领取腾讯云代金券