Spring Cloud - Netflix Hystrix实现断路器

一、前言?

1、Netflix Hystrix断路器是什么?

Netflix Hystrix是SOA/微服务架构中提供服务隔离、熔断、降级机制的工具/框架。Netflix Hystrix是断路器的一种实现,用于高微服务架构的可用性,是防止服务出现雪崩的利器。

2、为什么需要断路器?

在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。

另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。就跟数据瘫痪,会引起依赖该数据库的应用瘫痪是一样的道理。


当一个应用依赖多个外部服务,一切都正常的情况下,如下图:

如果其中一个依赖发生延迟,当前请求就会被阻塞

出现这种情况后,如果没有应对措施,后续的请求也会被持续阻塞

每个请求都占用了系统的CPU、内存、网络等资源,如果该应用的QPS较高,那么该应用所以的服务资源会被快速消耗完毕,直至应用死掉。如果这个出问题的依赖(Dependency I),不止这一个应用,亦或是受影响的应用上层也有更多的依赖,那就会带来我们前面所提到的服务雪崩效应。

所以,为了应对以上问题,就需要有支持服务隔离、熔断等操作的工具

二、Hystrix 简介

1、Hystrix具备哪些能力/优点?

  • 在通过网络依赖服务出现高延迟或者失败时,为系统提供保护和控制
  • 可以进行快速失败,缩短延迟等待时间和快速恢复:当异常的依赖回复正常后,失败的请求所占用的线程会被快速清理,不需要额外等待
  • 提供失败回退(Fallback)和相对优雅的服务降级机制
  • 提供有效的服务容错监控、报警和运维控制手段

2、Hystrix 如何解决级联故障/防止服务雪崩?

  • Hystrix将请求的逻辑进行封装,相关逻辑会在独立的线程中执行
  • Hystrix有自动超时策略,如果外部请求超过阈值,Hystrix会以超时来处理
  • Hystrix会为每个依赖维护一个线程池,当线程满载,不会进行线程排队,会直接终止操作
  • Hystrix有熔断机制: 在依赖服务失效比例超过阈值时,手动或者自动地切断服务一段时间

所以,当引入了Hystrix之后,当出现某个依赖高延迟的时候:

三、Hystrix 工作原理

1、Hystrix工作流

  • 1、创建HystrixCommand 或者 HystrixObservableCommand 对象
  • 2、执行命令execute()、queue()、observe()、toObservable()
  • 3、如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回
  • 4、检查熔断器状态,确定请求线路是否是开路,如果请求线路是开路,Hystrix将不会执行这个命令,而是直接执行getFallback
  • 5、如果和当前需要执行的命令相关联的线程池和请求队列,Hystrix将不会执行这个命令,而是直接执行getFallback
  • 6、执行HystrixCommand.run()或HystrixObservableCommand.construct(),如果这两个方法执行超时或者执行失败,则执行getFallback()
  • 7、Hystrix 会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。

这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。

在SpringCloud中应用:

加入hystrix依赖库,在pom.xml中添加如下内容:

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

在application.yml文件添加如下配置:

feign:
  hystrix:
    enabled: true

Feign接口中的内容:

@FeignClient(name="microservice-provider-user",fallback=FeignFallbackn.class)
public interface FeginInterfase {

	@RequestMapping(value="/getUserById/{id}",method=RequestMethod.GET)
	public User getUserById(@PathVariable("id") Long id);
	
	@RequestMapping(value="/getUserById2",method=RequestMethod.POST)
	public User getUserById2(@RequestBody User user);
}

定义实现Feign接口的实现类:

@Component
public class FeignFallbackn implements FeginInterfase{

	@Override
	public User getUserById(Long id) {
		User user = new User();
		user.setId(0L);
		return user;
	}

	@Override
	public User getUserById2(User user) {
		user.setId(0L);
		return user;
	}

}

当服务挂掉后,请求只走Feign接口的实现类中的方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值