Hystrix-超时机制和断路器模式
来源:互联网 发布:c语言模拟多线程 编辑:程序博客网 时间:2024/05/16 10:06
一 超时机制、断路器模式简介
1.1 背景
假设服务提供者响应非常缓慢,那么消费者对提供者的请求线程就会被等待,知道服务返回,在高并发高负载的场景下,如果不做任何处理,这种问题很有可能造成所有处理用户请求的线程的资源耗竭,而不能响应用户进一步请求。
如果服务消费者又是另外服务的提供者,那么有可能产生级联反应,导致其它的下一级服务消费者不可用,最终产生雪崩效应。
1.2 解决方案
1.2.1 超时机制
通过网络请求其他服务时,都设置超时。正常情况下,一个远程调用,即使毫秒就返回了。
当依赖的服务不可用的时候,或者因为网络问题,响应时间会变得很长(几十秒)。而通常情况下,一次远程调用对应了一个线程或者进程,如果响应太慢,那这个线程、进程就会得不到释放。而线程和进程是系统资源,如果大量线程、进程都不被释放,越积越多,服务资源就会被耗尽。所以我们必须设置超时请求。
1.2.2 断路器模式
类似于电短路的时候,跳闸。电流量过大,就会自动断开电路,避免电路升温,烧断电路或者电器。
当依赖的服务有大量超时的时候,再让新的请求去访问已经没有太大意义,只会无谓的消耗现有资源。譬如我们设置了超时时间为1秒,如果短时间有大量请求在1秒内得不到响应,往往意味着异常。此时就没有必要让更多的请求去访问这个依赖了,我们应该使用断路器避免资源浪费。
断路器可以实现快速失败,如果在一段时间内侦测到许多的类似的错误,就会强迫其以后的多个调用快速失败,不再请求所依赖的服务,从而防止应用程序不断的尝试执行可能失败的操作,这样应用程序可以继续执行而不用等待修正错误。断路器模式也可以使得应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
断路器模式就类似于那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生几次错误,然后决定使用允许操作继续,否则直接返回错误。
二 Hystrix传播Security Context或者SpringScope
如果你想将本地线程上下文传播到注解HystrixCommand中,默认的声明是不会起到这个作用的,因为它是在一个线程中启动的。你可以选择让Hystrix使用同一个线程,通过一些配置或直接写在注解上,通过使用isolation strategy属性。
比如:
@HystrixCommand(fallbackMethod ="stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")
}
)
同样的方式适用于如果你用@SessionScope 或者 @RequestScope。你应该知道什么时候去做这件事因为有些运行时异常报找不到scoped上下文。
你也可以选择设置hystrix.shareSecurityContext 属性为true。这样做会自动配置一个Hystrix 并发策略插件钩子,然后会将SecurityContext从你当前主线程
传输到一个使用Hystrix Command注解的地方。
三 Hysteria Health Indicator 及Metric System
3.1health indicator 健康指标
断路器的状态同样暴露在/health端点上。
{
"hystrix": {
"openCircuitBreakers": [
"StoreIntegration::getStoresByLocationLink"
],
"status": "CIRCUIT_OPEN"
},
"status": "UP"
}
3.2Hystrix Metrics Stream
使用Hystrix metricsstream需要引入依赖spring-boot-starter-actuator。这会暴露/hystrix.stream作为一个管理端点。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
四 Feign对Hystrix的支持
我们上面所说的熔断机制都是基于在方法上添加@HystrixCommand注解,然后通过属性fallbackMethod实现回退的。然而Feign是以接口形式工作的,他没有方法体,那么前面所述的方式是否依然适合Feign呢?
那么Feign要如何整合Hystrix呢?而且要如何实现Feign的回退呢?
Spring Cloud默认已经为Feign整合了Hystrix,只要Hystrix在项目的classpath中,Feign默认就会用断路器包裹的所有方法。
4.1 为Feign添加回退
首先添加fallback属性为FeignClient,并且指定一个class,这个class实现了接口
@FeignClient(name="microservice-provider-user",configuration=Configuration1.class,
fallback=HystrixClientFallback.class)
publicinterface UserFeignClient {
@RequestLine("GET /user/{id}")
public User findById(@Param("id") Longid);
}
创建实现了Feign接口的类,并且实现fallback方法:
@Component
publicclass HystrixClientFallbackimplements UserFeignClient {
@Override
public UserfindById(Long id) {
Useruser = new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
}
4.2 禁用单个FeignClient对Hystrix的支持
4.2.1 如果是某些Feign客户端想禁用Hystrix
@FeignClient(name="microservice-provider-user",configuration=Configuration1.class,
fallback=HystrixClientFallback.class)
publicinterface UserFeignClient {
@RequestLine("GET /user/{id}")
public User findById(@Param("id") Longid);
}
@Configuration
publicclass Configuration1 {
@Bean
@Scope("prototype")
public Feign.BuilderfeignBuilder() {
return Feign.builder();
}
}
4.2.2 如果是希望全局禁用
在application.yml中添加feign.hystrix.enabled=false即可
4.3 Feign使用fallbackFactory的属性打印fallback异常
如果有时候我们需要知道发生了什么异常,或者造成回退的原因是什么,我们应该怎么做呢?
我们可以在FeignClient注解上属性加上fallbackFactory属性
首先,创建一个类
publicclassHystrixClientFallbackFactory
implementsFallbackFactory<UserFeignClient>{
private static final Logger logger = LoggerFactory.getLogger
(HystrixClientFallbackFactory.class);
@Override
public UserFeignClientcreate(Throwable cause) {
/**
*----日志最好放在各个fallback方法中,而不要直接放在create方法中
*----否则在启动的时候,就会打印日志
*/
return new UserFeignClient(){
@Override
public UserfindById(Long id) {
HystrixClientFallbackFactory.logger.info
("fallback,causedby: "+cause);
Useruser = new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
};
}
}
然后:在Feign客户端的注解@FeignClient上加上属性
fallbackFactory
@FeignClient(name="microservice-provider-user",configuration=Configuration1.class,
fallbackFactory=HystrixClientFallbackFactory.class)
publicinterface UserFeignClient {
@RequestLine("GET /user/{id}")
public User findById(@Param("id") Longid);
}
Fallbackfactory属性还有其他用途, 我们可以让不同的异常返回不同的回退结果,从而使得Feign的回退更加灵活。例如:
publicclassHystrixClientFallbackFactory
implementsFallbackFactory<UserFeignClient>{
private static final Logger logger = LoggerFactory.getLogger
(HystrixClientFallbackFactory.class);
@Override
public UserFeignClientcreate(Throwable cause) {
/**
*----日志最好放在各个fallback方法中,而不要直接放在create方法中
*----否则在启动的时候,就会打印日志
*/
return new UserFeignClient(){
@Override
public UserfindById(Long id) {
HystrixClientFallbackFactory.logger.info
("fallback,causedby: "+cause);
Useruser = new User();
if (cause instanceof IllegalArgumentException) {
user.setId(-1L);
}else {
user.setId(-2L);
}
user.setName("默认用户");
return user;
}
};
}
}
五Hystrix的监控
5.1 指标化监控
处理实现容错外,Hystrix还提供了近乎实时的监控。HystrixCommand和HystrixObservableCommand在执行时,会生成执行结果和运行指标,比如每秒执行的请求数,成功数等,这些监控数据在对分析应用时很有用。
Spring-cloud-starter-hystrix已包含该模块,在此基础上,只需为项目添加spring-boot-starter-actuator,就可以使用/hystrix.stream端点获得Hystrix的监控信息了。
然后就可以访问了/hystrix.stream
对于Feign项目的Hystrix监控,我们需要在启动类上加上@Enable-
CircuitBreaker,这样就可以使用/hystrix.stream
5.2 可视化监控(HystrixDashboard)
前面的方式我们很难通过肉眼迅速看出当前系统运行状态,因为是以文字演示的,使用Hystrix 仪表盘,我们一眼就可以看出当前的运行状态,让监控数据可视化,图形化。
首先:添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
其次: 在启动类上添加@EnableHystrixDashboard,我么修改端口为8030
@SpringBootApplication
@EnableHystrixDashboard
publicclassMovieServiceHystrixDashBoardRunner {
@Bean
@LoadBalanced
public RestTemplaterestTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(MovieServiceHystrixDashBoardRunner.class,args);
}
}
server:
port: 8030
最后:这样一个简单的Hystrix Board就完成了,我们知道,我们并没有把Hystrix Dashboard注册到Eureka Server上,访问localhost:8030/
Hystrix
六 Turbine
前面我们已经知道,/hystrix.stream端点用于监控单个微服务实例,但是微服务架构体系中一般会包含若干个微服务,在生产环境中每一个微服务都可能会集群部署的,监控单个实例的话,就需要在Hystrix Dashboard上切换想要监控的地址,这显示是很不方便的,怎么办呢?
6.1Turbine简介
Turbine是一个聚合Hystrix监控数据的工具,他可以将相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,从而让集群监控的更加方便。
6.2 使用turbine监控多个微服务
# 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
# 启动类添加注解@EnableTurbine
@SpringBootApplication
@EnableTurbine
publicclassTurbineHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineHystrixApplication.class,args);
}
}
# 修改application.yml配置文件
turbine.aggregator.clusterConfig: 集群名字,多个逗号分割
turbine.appConfig: 微服务名称,多个逗号分割
# 访问
localhost:8031/turbine.stream?cluster=MICROSERVICE-CONSUMER-FEIGN-WITH-HYSTRIX
或者
localhost:8031/turbine.stream?cluster=MICROSERVICE-CONSUMER-RIBBON-WITH-HYSTRIX
如果启动了 Hystrix Dashboard,那么可以在Dashboard可视化展示数据
- Hystrix-超时机制和断路器模式
- 超时机制、断路器模式简介
- 【SpringCloud】(十一):超时机制和断路器及 Hystrix简单实践
- [java]微服务架构连载No4 Hystrix+Dashboard+Turbine实现断路器(限流,超时,异常...)和服务监控
- SpringCloud Hystrix 断路器
- 断路器(Hystrix)
- SpringCloud--断路器(Hystrix)
- 4.断路器Hystrix
- SpringCloud:断路器(Hystrix)
- SpringCloud断路器(Hystrix)
- 5.断路器(Hystrix)
- spring cloud: Hystrix断路器(熔断器)
- spring cloud: Hystrix断路器(熔断器)
- Spring Cloud 断路器Hystrix实战
- Spring Cloud 中的断路器 hystrix
- spring cloud: Hystrix断路器(熔断器)
- 十二、断路器-Hystrix 的认识
- 断路器hystrix原理及使用
- < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />详解
- 用jquery在元素上添加的样式,对当前ajax动态加载过来的一样的元素无效
- 实战案例:如何用Word制作收款单
- java Servlet快速入门
- 小贷、p2p项目上线的基本流程
- Hystrix-超时机制和断路器模式
- Installing Ionic
- 文章标题C#客户端发送Http请求与服务端通信
- table标签中设置tr的行间距
- 【机器学习】集成学习
- 常用的排序算法性能分析(2)—— 归并排序、快速排序
- 根据进程句柄获得可执行文件路径的几种方法
- 关于QT5.4+VS2010\VS2013使用过程中,中文乱码的问题
- fresco 加载本地路径图片,并修改图片尺寸