feign使用_如何用RestTemplate和Feign消费服务时,使用熔断器Hystrix?

前言

前面讲述了如何使用RestTemplate和Feign去消费服务,并详细地讲述了Ribbon 做负载均衡的原理和Feign的工作原理。本章将讲述如何在用RestTemplate和Feign消费服务时使用熔断器Hystrix, 将从以下7个方面进行讲解。

  • 什么是Hystrix。

  • Hystrix 解决了什么问题。

  • Hystrix 的工作原理。

  • 如何在 RestTemplate和Ribbon作为服务消费者时使用Hystrix。

  • 如何在Feign作为服务消费者时使用Hystrix。

  • 如何使用Hystrix Dashboard监控熔断器的状况。

  • 如何使用 Turbine聚合多个Hystrix Dashboard。

什么是Hystrix

在分布式系统中,服务与服务之间的依赖错综复杂,-种不可避免的情况就是某些服务会出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞。Hystrix是Netlix公司开源的一一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性。

Hystrix 解决了什么问题

在复杂的分布式系统中,可能有几十个服务相互依赖,这些服务由于某些原因,例如机房的不可靠性、网络服务商的不可靠性等,导致某个服务不可用。如果系统不隔离该不可用的服务,可能会导致整个系统不可用。

例如, 对于依赖30个服务的应用程序,每个服务的正常运行时间为9.99%,对于单个服务来说,99.99%的可用是非常完美的。

有9.9939 = 99.7%的可正常运行时间和0.3%的不可用时间,那么10亿次请求中有300000次失败,实际的情况可能比这更糟糕。

如果不设计整个系统的韧性,即使所有依赖关系表现良好,单个服务只有0.01%的不可用,由于整个系统的服务相互依赖,最终对整个系统的影响是非常大的。

在微服务系统中,一个用户请求可能需要调用几个服务才能完成。如图8-1所示,在所有的服务都处于可用状态时,一个用户请求需要调用A、H、1和P服务。

2e1f130381bf867fe17ca47d3125bd07.png

当某一个服务,例如服务I,出现网络延迟或者故障时,即使服务A、H和P可用,由于服务I的不可用,整个用户请求会处于阻塞状态,并等待服务I的响应,如图8-2所示。

在高并发的情况下,单个服务的延迟会导致整个请求都处于延迟状态,可能在几秒钟就使整个服务处于线程负载饱和的状态。

某个服务的单个点的请求故障会导致用户的请求处于阻塞状态,最终的结果就是整个服务的线程资源消耗殆尽。由于服务的依赖性,会导致依赖于该故障服务的其他服务也处于线程阻塞状态,最终导致这些服务的线程资源消耗殆尽,直到不可用,从而导致整个问服务系统都不可用,即雪崩效应。

为了防止雪崩效应,因而产生了熔断器模型。Hystrix是在业界表现非常好的一个熔断器模型实现的开源组件,它是Spring Cloud组件不可缺少的一部分。

82dc16570ca3a4532a3a361e0b9f637d.png

Hystrix的设计原则

总的来说,Hystrix 的设计原则如下。

  • 防止单个服务的故障耗尽整个服务的Servlet容器(例如Tomcat)的线程资源。

  • 快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等待。

  • 提供回退 (fallback) 方案,在请求发生故障时,提供设定好的回退方案。

  • e使用熔断机制,防止故障扩散到其他服务。

  • 提供熔断 器的监控组件Hystrix Dashboard,可以实时监控熔断器的状态。

Hystrix的工作机制

第2章的图2-5展示了Hystrix 的工作机制。首先,当服务的某个API接口的失败次数在一定时间内小于设定的阀值时,熔断器处于关闭状态,该API接口正常提供服务。当该API接口处理请求的失败次数大于设定的阀值时,Hystrix判定该API接口出现了故障,打开熔断器,这时请求该API接口会执行快速失败的逻辑( 即fallback 回退的逻辑),不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器,一段时间后会处于半打开状态,并将--定数量的请求执行正常逻辑。剩余的请求会执行快速失败,若执行正常逻辑的

请求失败了,则熔断器继续打开:若成功了,则将熔断器关闭。这样熔断器就具有了自我修复的能力。

在 RestTemplate 和Ribbon 上使用熔断器

本节以案例的形式讲解如何在RestTemplate和Ribbon作为服务消费者时使用Hystrix熔断器。本节的案例在上一章的案例基础之上进行改造。在上一章的eureka- rbbon-client工程中,我们使用RestTempalte 调用了eureka-client 的“hi”API接口,并用Ribbon做了负载均衡,本节在此基础上加Hystrix熔断器的功能。

首先在工程的pom文件中引用Hystrix 的起步依赖spring-cloud strter-hystrix,代码如下:

<dependency>
<groupId>org. springf ramework. cloudgroupId>
<arti factId>spring-cloud-starter-hystrixartifactId>
dependency>

然后在Spring Boot的启动类
EurekaRibbonClientApplication加上@EnbleHystrix注解开启

Hytrix的熔断器功能,代码如下:

@SpringBootAppication
@EnableEurekaClient
eEnableHystrix
public class EurekaRibbonClientApplication 1
public. static void main(Stringl] args) (
SpringApplication. run (EurekaRibbonClientApplication.class, args);

修改RibbonService 的代码,在hi0方法上加@HystrixCommand注解。有了@HystrixCommand注解,hi0方法就启用Hystrix熔断器的功能,其中,fllbackMethod 为处理回退( fllback)逻辑的方法。在本例中,直接返回了一个字符串。在熔断器打开的状态下,会执行fllback逻辑。

fallback的逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调度其他服务,这样方便执行快速失败,释放线程资源。如果一定要在fallback逻辑中远程调度其他服务,最好在远程调度其他服务时,也加上熔断器。案例代码如”F:

@eservice
publlc class Ribbonservice
BRutowired
RestTemplate restTemplate;
@Hystri xCommand (rallbackMethod一"hiError")
public String hi(string name) 1
return restTemplate 。getForobject ("http:/ /eureka-c1 ient/hi ?name" "+name, string.class);
publie string hiError (string name)i
return "hi, "+name+" , sorry,error!";

依次启动工程eureka-server. eureka-client 和eureka-ribon-client.等所有的工程都启动完毕,在浏览器上访问htp://o/alhost:.8765/hih浏览器会显示:

hi forezp,i am from port:8762

关闭eurcka-client,即它处于不可用的状态,此时erekriboneclient无法调用eureka-client的“hi”接口,访问ht:talhost:8765/hih5h浏览器会显示:

Ihi,forezp, sorry,error!

由此可见,当eureka-client 不可用时,调用eureka-ribbon-client 的“/hi" 接口会进入,RibbonService类的“hi" 方法中。由于eureka-client没有响应,判定eureka-client 不可用,开启了熔断器,最后进入了fllbackMethod 的逻辑。当熔断器打开了,之后的请求会直接执行fallbackMethod的逻辑。这样做的好处就是通过快速失败,请求能够得到及时处理,线程不再阻塞。

在Feign上使用熔断器

由于Feign的起步依赖中已经引入了Hystrix 的依赖,所以在Feign中使用Hystrix不需要引入任何的依赖。只需要在eureka-feign-client 工程的配置文件application.yml 中配置开启Hystrix的功能,配置文件aplicatin.yml中加以下配置:

feign:

hystrix:

enabled: true

然后修改eureka-feign-client 工程中的EurekaClientFeign 代码,在@FeignClient 注解的fllback配置加上快速失败的处理类。该处理类是作为Feign熔断器的逻辑处理类,必须实现被@FeignClient修饰的接口。例如案例中的HiHystrix 类实现了接口EurekaClientFeign, 最后需要以Spring Bean的形式注入loC容器中。代码如下:

@FeignClient (value - "eureka-client",
configuration = FeignConfig.class,fallback = HiHystrix.class)
public interface EurekaClientFeign (
eGetMapping(value一"/hi")
string sayHiFromClientEureka (8RequestParam(value一"name") string name);

HiHysrix作为熔断器的逻辑处理类,需要实现EurekaClientFeign 接口,并需要在接口方法sayHiFromClientEureka0里写处理熔断的具体逻辑,同时还需要在HiHytrix 类上加@Component注解,注入loC容器中。代码如下:

@Component
public class HiHystrix implements EurekaClientFeign (
loverride
public string sayHiFromClientEureka(string name) (
return "hi, "tname+" , sorry, error!";

依次启动工程eureka-server 、cureka-client 和eureka-feign-client. 在浏览器上访问htp://lcahost:8765/hiaj浏览器会显示:

hi forezp,i am from port:8762

关闭eureka-client,即它处于不可用的状态,此时eureka-feign-lient无法调用eureka-client的“hi”接口,在浏览器上访问htt//ht:8765/hih浏览器会显示:

hi, forezp, sorry,error!

由此可见,当eureka-client不可用时,eureka-feign-clien进入了fllbak 的逻辑处理类(即HiHystrix),由这个类来执行熔断器打开时的处理逻辑。

使用 Hystrix Dashboard监控熔断器的状态

在微服务架构中,为了保证服务实例的可用性,防止服务实例出现故障导致线程阻塞,而出现了熔断器模型。熔断器的状况反映了一个程序的可用性和健壮性,它是一个重要指标。

Hystrix Dashboard是监控Hystrix的熔断器状况的一一个组件, 提供了数据监控和友好的图形化展示界面。本节在上一t节的基础上,以案例的形式讲述如何使用Hystrix Dashboard监控熔断器的状态。

在 RestTemplate中使用Hystrix Dashboard

改造上一节的工程, 首先在eureka-ibon-client工程的pom文件上加上Actuator的起步依赖、Hysrix Dashboard的起步依赖和Hystrix的起步依赖,这3个依赖是必需的。代码如下:

<dependency>
<groupId>org. springfr amework . bootgroupId>
<artifactId>spring-boot-starter- actuatorartifactId>
dependency>
<dependency>
<groupId>org. springframework. cloudgroupId>
<artifactId>spring-cloud-starter -hystrix-dashboardarti factId>
dependency>
<dependency>
<groupId>org. springframework. cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
dependency>

在程序的启动类
EurekaRibbonClientApplication 加上@EnableHystrixDashboard开启Hystrix Dashboard 的功能,完整的代码如下:

@SpringBootApplication
@EnableEurekaC1 ient
@EnableHystrix
@EnableHystrixDashboard .
public class EurekaRibbonCl ientApplication {
public static void main(String[] args) {
SpringApplication. run (EurekaRibbonClientApplication.class, args);

依次启动工程eureka-server、 eureka-client 和eureka-ribbon-client。在浏览器上访问htp:/locahost 8765/hi.然后在浏览器上访问
htt:/calho/t:8764hyhtrixstreamt,浏览器上会显示熔断器的数据指标,如图8-3所示。

87ba17cec4342a5c0b54cbb343f07feb.png

在浏览器上访问 HTTP://localhost:8764/hystrix ,浏览器显示的界面如图 8-4 所示。

3a12f53ae98888a2114473119113b68c.png

在界面上依次填写 htφ //localho st:8764/hystr x.stream 2000 forezp (这个可 以随意填写)单击“ monitor ”,进入页面,如图 8-5 示。

06e18e2314310daa9664d1cf6ae5c4f9.png

在该页面显示了熔断器的各种数据指标 这些数据指标所表示的含义如图8 -6 该图来自于 Hystrix 官方文档,更多信息可以查阅官方文档,文档地址 https: //github.com/Ne ix/H ystrix/wiki/Dashboard。

791a2c0e7928559d5eb32c458bc11b51.png

在Feign中使用Hystrix Dashboard

同eureka-ribbon-client类似,eureka-feign-client工程的pom文件需要加上Actuator、Hystrix和Hystrix Dashboard的起步依赖。可能有读者会疑惑: Feign 不是自带Hystrix吗?为什么还需要加入spring cloud-starter-hystrix?这是因为Feign 自带的Hystrix 的依赖不是起步依赖。

Feign的起步依赖包含的依赖如下:

<dependency>
<groupId>org. springf r amework. bootgroupId>
<artifactId>spring-boot-starter- actuatorartifactId>
dependency>
<dependency>
<groupId>org . spr ingf ramework. cloudgroupId>
<arti factId>spring-cloud-starter-hystrix-dashboardartifactId>
dependency>
<dependency>
<groupId>org. springframework.cloudgroupId>
<arti factId>spring-cloud-starter-hystrixarti factId>
dependency>

需要在程序的启动类
EurekaFeignClientApplication 加上注解@ EnableHystrixDashboard 开启HystrixDashboard的功能。完整的代码如下:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
publie class EurekaFeignCl ientAppication
public static void main(stringl] args) (
SpringApplication. run (EurekaFeignClientAppication.clas, args);}
}

只需要上述两步就可以在Feign中开启Hytrix Dashboard的功能。在浏览器上展示HystrixDashboard的操作步骤同上一节,本节不再演示。

使用Turbine聚合监控

在使用HystrixDashboard组件监控服务的熔断器状况时,每个服务都有一个HystrixDashboard主页,当服务数量很多时,监控非常不方便。为了同时监控多个服务的熔断器的状况,Ntlix 开源了Hystrix 的另- -个组件Turbine. Turbine 用于聚合多个Hystrix Dashboard,

将多个Hystrix Dashboard组件的数据放在一一个页面上展示,进行集中监控。

在上一节的例子上继续进行改造,在主Maven工程下新建一个Module工程,做为Turbine聚合监控的工程,取名为eureka-monitor-client.首先,在工程的pom文件引入工程所需的依赖,包括turbine、actuator 和test的起步依赖,完整的代码如下:

<dependenciea>
<dependency>
<groupId>org.springtramework. cloud/groupId>
<artifactId>spring-cloud- starter-turbineartifactId>
dependency>
<dependency>
<groupId>org. springf ramework。bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org. springframework . bootgroupId>
<artlfactid>spring-boot-starter-testarti factId>
<scope>testscope>
dependency>
dependencles>

然后在工程的配置文件application 加上相关的配置,具体配置代码如下:

spring:
application. name: service-turbine
server:
port: 8769
turbine:
aggregator:
clusterConfig: default
appConfig: eureka-ribbon-cl ient, eureka- feign-client
cluste rNameExpression: new String ("default")
eureka:
client:
serviceUrl :
defaultZone: http: //localhost:8761/eureka/

上述配置代码指定了工程的端口号为8769,服务名为service turbine。turbine aggregator.

clusterConfig配置了需要监控的服务名,如本例中的eureka-ribbon-client 和eureka-feign-client。

clusterNameExpression默认为服务名的集群,此时用默认的即可。
turbine.aggregator.clusterConfig可以不写,因为默认就是default。最后指定了服务注册中心的地址为ht://calhost:876 1/eureka/。

启动工程eureka-server、eureka-client、eureka-ribbon-client 和eureka-monitor-client。在浏览器上访问htp://localhost:8764/hi?name=forezp和ht:/calhost:8765/hi?name= forezp。

在浏览器上打开网址
htp:/ocalhost:8765/hystrix,这个界面为Hystrix Dashboard界面。在界面上依次输入监控流的Url地址
htp://ocalhost:8769/turbinestream监控时间间隔2000毫秒和title,单击“monitor”,可以看到如图8-7所示的界面。

e9e7348ecdd6bd4981cfe8b52e435cdc.png

从图 8-7 中可以 到,这个页面聚合了 eureka-ribbon-client eureka-feign-client Hystrix Dashboard 数据。

可以转发关注小编,每天更新干货文章~~

感谢大家支持~~~

b7a2f903bff25caf5e27cd9c0a227897.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值