容错框架之Hystrix小记
微服务框架下,一个服务依赖于很多服务。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等,一个被调用服务出问题可能导致调用者不能正常调用其他服务。我们要构建稳定、可靠的分布式系统,就必须要有一套容错方法来应对这些情况。
Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程池隔离、信号量隔离、熔断(Circuit Breaker)、降级回退(Fallback),还支持请求缓存(Request Caching)、请求合并(Request Collapsing)等。应用场景如网关服务调用订单服务、商品服务、用户服务。
Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
1 基本概念
public class GetOrderCommand extends HystrixCommand<List> { OrderService orderService; public GetOrderCommand(String name){
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ThreadPoolTestGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("testCommandKey"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(name))
.andCommandPropertiesDefaults(
HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(5000)
)
.andThreadPoolPropertiesDefaults(
HystrixThreadPoolProperties.Setter()
.withMaxQueueSize(10) //配置队列大小
.withCoreSize(2) // 配置线程池里的线程数
)
);
} @Override
protected List run() throws Exception {
return orderService.getOrderList();
} public static class UnitTest {
@Test
public void testGetOrder(){
// new GetOrderCommand("hystrix-order").execute();
Future<List> future =new GetOrderCommand("hystrix-order").queue();
} }
}
每个服务对应的commond都有单独的线程池来负责执行。这样当调用者调用多个服务时,某个服务发生异常不会影响调用者对其他服务的调用。
Commond可同步或异步执行:execute()、queue()、observe()、toObservable()
2 内部执行流程
3 容错技术
3.1 依赖隔离(Dependency Isolation)
依赖隔离是指采用某种处理方式使得对一个依赖的调用阻塞时不影响调用方对其他依赖的调用。
显然,最简单的方式是每次调用都起一个新线程执行调用处理,这理论上是可行的,但实际上不会被采用,因为很耗费资源(频繁创建线程、可创建线程数有限等)。解决:仍采用多线程,但需要进一步改造——限制可创建的线程数,有线程池、信号量方式。
3.1.1 线程池隔离
每个依赖的服务的Client(如订单服务的OrderClient)都被包装成HystrixCommand或HystrixObservableCommand。
commond相当于是目标服务的Client的代理,每个服务对应一个commond,每个common内部有个线程池,用来负责执行对目标服务的调用。这样的优点之一是:在调用者方面,一个服务调用阻塞(如超时)时不会影响对其他服务的调用,将影响范围限制在了一个服务内;通过线程池大小控制并发能力。
the isolation provided by thread pools allows for the always-changing and dynamic combination of client libraries and subsystem performance characteristics to be handled gracefully without causing outages.
示意图:
线程池技术本质上与数据库等的连接池类似,一方面用于复用线程/连接以免重复创建线程/连接、另一方面用于限制对服务端的并发访问数。这里的线程池隔离与数据库连接池的区别在于:前者由于要对接多个后端服务而后者专为一个后端服务(数据库),故前者需要为每个服务对应一个线程池而后者只需要一个连接池,两者本质上是一样的。(其实很多技术本质上是一样的,透过现象看本质!)
3.1.2 信号量隔离
此模式使用的场景是被调用的依赖是不耗时的操作时(如从当前进出内存取数据等而非进行RPC)。该模式下每次调用commond时直接用当前线程来执行对目标服务的调用,因此实际上是做不到依赖隔离的——当前服务同时调用多个服务时一个服务的阻塞会影响对其他服务的调用。其主要作用是控制对一个依赖的并发调用个数,所以称counter更贴切。
线程池隔离与信号量隔离的区别:
THREAD
— it executes on a separate thread and concurrent requests are limited by the number of threads in the thread-pool。(HystrixCommand推荐用此)SEMAPHORE
— it executes on the calling thread and concurrent requests are limited by the semaphore count。(HystrixOvservableCommand推荐用此)
3.2 断路器(Circuit Breaker)
6个核心参数:
1、circuitBreaker.enabled
是否启用熔断器,默认是TURE。
2、circuitBreaker.forceOpen
熔断器强制打开,始终保持打开状态。默认值FLASE。
3、circuitBreaker.forceClosed
熔断器强制关闭,始终保持关闭状态。默认值FLASE。
4、circuitBreaker.errorThresholdPercentage
设定错误百分比,默认值50%,例如一段时间(10s)内有100个请求,其中有55个超时或者异常返回了,那么这段时间内的错误百分比是55%,大于了默认值50%,这种情况下触发熔断器-打开。
5、circuitBreaker.requestVolumeThreshold
默认值20。意思是至少有20个请求才进行errorThresholdPercentage错误百分比计算。比如一段时间(10s)内有19个请求全部失败了。错误百分比是100%,但熔断器不会打开,因为requestVolumeThreshold的值是20.。
6、circuitBreaker.sleepWindowInMilliseconds
半开试探休眠时间,默认值5000ms。当熔断器开启一段时间之后比如5000ms,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。
3.3 降级回退(Fallback)
即指定在调用目标服务失败时进行怎样的处理,通常是返回个默认值。
3.4 请求合并(Request Collapsing)
3.5 请求缓存(Request Caching)
4 弊端
牛逼吹了一堆,实际使用时发现的弊端。
关于熔断功能:熔断有connectionTimeout、readTimeout,前者为建立连接过程的超时时间、后者为连接成功后发起请求到收到调用结果的超时时长。启用熔断后,发起服务调用时,若达到了任一个超时时间则调用方会认为服务不可用,然而若达到了readTimeout,实际上可能被调用服务已经在执行,而调用方却认为服务不可用了,这就会造成不同服务间的数据不一致,除非调用方在认为服务不可用时对被调用服务进行回滚(分布式事务等)。因此readTimeout是个很重要的参数,定太短了会导致不同服务上的数据不一致,然而这个参数通常不好定,特别是服务调用链很长时更难以确定该设什么值。
5 参考资料
https://www.jianshu.com/p/3e11ac385c73
容错框架之Hystrix小记的更多相关文章
- Dubbo服务容错(整合hystrix)
简介:Hystrix旨在通过控制那些访问远程系统.服务和第三方库的节点从而对延迟和故障提供更强大的容错能力,Hystrix具备拥有回退机制和断路器功能的线程和信号隔离.请求缓存和请求打包以及监控和配置 ...
- SpringCloud初体验:三、Feign 服务间调用(FeignClient)、负载均衡(Ribbon)、容错/降级处理(Hystrix)
FeignOpenFeign Feign是一种声明式.模板化的HTTP客户端. 看了解释过后,可以理解为他是一种 客户端 配置实现的策略,它实现 服务间调用(FeignClient).负载均衡(Rib ...
- SpringCloud系列之服务容错保护Netflix Hystrix
1. 什么是雪崩效应? 微服务环境,各服务之间是经常相互依赖的,如果某个不可用,很容易引起连锁效应,造成整个系统的不可用,这种现象称为服务雪崩效应. 如图,引用国外网站的图例:https://www. ...
- SpringCloud之Hystrix:集群容错框架
分布式环境中,可能会有一些被依赖的服务会失效,影响系统的稳定运行.Hystrix通过添加延迟阈值以及容错的逻辑,以控制分布式系统间组件的交互.Hystrix通过隔离服务间的访问点.停止它们之间的级联故 ...
- 微服务容错限流Hystrix入门
为什么需要容错限流 复杂分布式系统通常有很多依赖,如果一个应用不能对来自依赖 故障进行隔离,那么应用本身就处在被拖垮的风险中.在一个高流量的网站中,某个单一后端一旦发生延迟,将会在数秒内导致 所有应用 ...
- 遗传算法框架GAFT优化小记
前言 前段时间一直在用自己写的遗传算法框架测试算法在优化力场参数的效果,但是跑起来效率很慢,因为适应度函数需要调用多次力场程序计算能量,但是还是比我预想中的慢我也没有及时对程序进行profiling和 ...
- 【Spring Cloud】服务容错保护:Hystrix(四)
一.雪崩效应 在微服务架构中,由于服务和服务之间可以互相调用,一项工作的完成可能会依赖调用多个微服务模块,但由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就 ...
- 2.4容错保护:Hystrix
在ribbon使用断路器 改造serice-ribbon 工程的代码,首先在pox.xml文件中加入spring-cloud-starter-hystrix的起步依赖: 引入 <dependen ...
- Spring Cloud组件使用/配置小记
仅使用,无多少技术含量,权记于此以备忘. 微服务架构下的主要组件 服务注册组件:Consul.Etcd等 网关:Zuul.Spring Cloud Gateway等 容错框架:Hystrix 负载均衡 ...
随机推荐
- python中count和index
str = [1,2,3,4,5] #定义一个列表 str = 3 #列表3 str [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] str.count(1 ...
- spring 注解aop调用invoke()
public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlAp ...
- 尽解powershell的workflow
尽解powershell的workflow -------1[简介]--------- Microsoft .NET Framework 4.0 发布于2010年4月左右..net4 的新特性,是并行 ...
- redis之线程IO模型
非阻塞 IO 当我们调用套接字的读写方法,默认它们是阻塞的,比如 read 方法要传递进去一个参数n,表示读取这么多字节后再返回,如果没有读够线程就会卡在那里,直到新的数据到来或者连接关闭了,read ...
- python学习笔记 - socket通信
socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- C++ 在线编译器(支持 C++11)
C++11 的 Inheriting constructors 特性在 GCC 4.8 以前的版本及 VS2013 中都没有支持,测试起来比较麻烦,所以搜集到了几个支持 GCC 4.8 及更高版本的在 ...
- Docker Hub 使用初探
Docker Hub 使用初探 —— 魏刘宏 2019.10.26 容器的话题越来越热,今天我也来试试容器的使用,我们以 Docker Hub 为例. Docker Hub 官网为 https://h ...
- Python【day 13】内置函数01
1.python3.6.2 一共有 68个内置函数2.分成6个大类 1.反射相关-4个 2.面向对象相关-9个 3.作用域相关--2个 1.globlas() #注意:最后是s,复数形式 查看全局作用 ...
- Docker(一) - CentOS7中安装Docker - (视频教程)
Docker的使用越来越多,安装也相对简单.本文使用视频的方式展示在CentOS7系统中安装Docker,本文更适合于准备入门学习Docker的童靴. 以下视频,请带上耳机开始聆听 (双击全屏播放) ...
- JavaScript Date 日期属性和方法
JavaScript 日期(Date) Date对象用于处理日期和时间.使用对象new Date()创建日期.实例化日期有四种方式: var d1 = new Date(); var d2 = new ...