Hystrix

Posted Java Miraculous

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hystrix相关的知识,希望对你有一定的参考价值。

现在的电商网站基本都是微服务,会员、订单、商品(库存)、购物车,这些模块都是独立的应用,模块之间通过RPC进行调用(我上家公司用的springmvc或者springboot,RPC框架是dubbo,现在的公司就是springcloud,可见springcloud是个趋势),正常情况下,一个用户登录,登录完选商品,选完商品提交订单,提交订单的时候需要减库存,假如现在库存接口响应缓慢,那么从订单系统过来的请求就会等待,平时QPS小的时候倒是没啥大的问题,最多就是响应慢点,但假如是大促期间出现这问题,短时间内超高的请求会造成线程池很快打满,商品系统瘫痪,订单系统由于等待商品系统的响应也最终瘫痪,所以一个系统出问题不可怕,可怕的是引起别的系统也出问题。



为了解决这样的问题,产生了断路器等一系列的服务保护机制。断路器源于电路中的一种装置,如果家里有地方发生短路,短路后极大的电流被断路器感知,它就会断开电路,避免电路过载而引发火灾,在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待,这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
springcloud Hystrix实现了断路器,Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。
  • 一、通过一个简单的例子学习下springcloud Hystrix

注:我们还是以在Eureka文章用的demo为例
  • 1.1、启动eureka-server

在target目录打开cmd,运行:
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
再打开一个cmd,运行:
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

  • 1.2、启动provider

先启动一个,然后改下端口再启动另外一个
注:之前在讲Eureka的region和zone时,两个provider的zone故意改的不一样,这里要一样,不然客户端会一直请求同一个zone里的实例,看不到负载均衡的效果

Hystrix

  • 1.3、启动consumer

Hystrix

浏览器访问: http://localhost:8090/ribbon-consumer

Hystrix

多访问几次,可以看到provider的控制台,两个实例交替打印

Hystrix

Hystrix

这时候停掉一个实例,在浏览器里继续刷新请求

Hystrix

可以看到,多刷几次,有一半的请求都是会报错,另一半正常,因为客户端加了Ribbon进行轮询请求两台实例。大概过了一分多钟后,Eureka把那台挂掉的实例剔除后,就不会再报错了(因为客户端拉取到的服务提供者实例只剩下一台正常的了)。你是不是觉得这样也可以,只不过需要等Eureka把挂掉的实例剔除后才正常,但这个90s时间等不起啊,假如是双十一,你知道1s是多少钱吗?所以需要服务挂掉后立马就让客户端感知到,下面开始引入springcloud Hystrix。
在consumer工程里添加依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId></dependency>

Hystrix

在启动类ConsumerApplication里添加注解@EnableCircuitBreaker

Hystrix

我们新增一个假的接口层HelloService
package com.example.consumer.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;
@Servicepublic class HelloService {
@Autowired private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallBack") public String helloService(){ ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://PROVIDER/hello?name={1}", String.class, "猪小屁"); String body = responseEntity.getBody(); return body; }
    public String helloFallBack(){ return "小屁繁忙,请稍后重试"; }}

Hystrix

其实相当于把逻辑放到了一个业务类里,然后我们在controller里直接注入这个业务类,调用方法即可。

Hystrix

现在把刚才那个停掉的provider重新启动,让它注册到eureka,然后启动consumer,在浏览器里请求: http://localhost:8090/ribbon-consumer ,多刷几次,响应正常,然后将provider的实例停掉一个,再刷。

Hystrix

你会发现Hystrix起作用了,除了服务挂掉这种情况外,我们还可以模拟下服务阻塞(就是长时间无响应)

修改provider里的接口里修改:

Hystrix

为了更精准地观察断路器的触发,在消费者调用函数中做一些时间记录

Hystrix

然后重新启动provider和consumer,在浏览器里访问 http://localhost:8090/ribbon-consumer ,要多刷几次,因为线程的休眠时间是随机的。

书上说的Hystrix的默认超时时间是2000ms,但是实测超过1000ms就会触发断路器了。你们可以试试。
好了,Hystrix的基本使用就到这里了,其实Eureka、Ribbon、Hystrix都是springcloud里的组件,现在微服务盛行,这些都是必须要掌握的。
注:demo已同步
链接: https://pan.baidu.com/s/1DK33NEHovozr5-FrQWW5aQ
提取码 关注公众号,回复 springcloud 获取

以上是关于Hystrix的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud学习--- Hystrix详解(附代码包)

无法在 Hystrix 仪表板上查看 Hystrix 报告

SpringCloud- 第六篇 Hystrix参数配置

从 Hystrix 获取异常

用100行代码手写一个Hystrix

Hystrix 断路器不打开电路