Hystrix豪猪的简单学习
Hystrix 简介
分布式项目中,由于各微服务间存在多重依赖,当其中某一个微服务调用失败时,很可能会引起联级失败,从而产生“雪崩”效应。Hystrix则是为了解决上述问题应运而生的,为项目提供一种保护机制。
Hystrix 解决方案
1.线程隔离
Hystrix为每个服务调用分配一定数量的固定线程池,将各服务隔离开来,这样即使某一服务调用失败,也只有分配给失败服务的线程池会被堵塞,其他的线程不会受到影响。
2.服务熔断(降级)
当服务调用失败时,Hystrix会进行一个短时间的等待,等待超时后,Hystrix会快速返回一个友好的错误讯息,通知客户端进行服务降级,进而释放堵塞线程。
触发服务降级的条件一个是返回超时,一个是线程已满。
Hystrix之所以要做服务降级处理,是为了保证项目中核心服务有足够的线程资源。
2.1 服务降级的具体实现步骤
1.添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2.启动类上添加@EnableCircuitBreaker注解(@SpringCloudApplication注解包含了@EnableCircuitBreaker)
//@SpringBootApplication //@EnableDiscoveryClient //@EnableCircuitBreaker @SpringCloudApplication public class CustomerApplication { public static void main(String[] args) { SpringApplication.run(CustomerApplication.class,args); } @Bean @LoadBalanced public RestTemplate restTemplate1(){ return new RestTemplate(); } }
3.自定义降级处理方法,在需要做降级处理的方法加上注解@HystrixCommand(defaultFallback = "userFallback")
// @HystrixCommand(defaultFallback = "userFallback") @HystrixCommand public String test(@PathVariable("id") Long id){ return restTemplate.getForObject("http://user-service/user/"+id, String.class); } //服务降级处理方法 public String userFallback(){ return "很抱歉,目前服务器忙,请稍后再试!"; }
4.配置文件中自定义超时时间(默认超时时间1000毫秒)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
2.2 服务熔断
服务熔断是基于服务超时降级处理的一种进阶处理,当某一服务调用,在一定次数(超过阈值,阈值默认20次)的请求中,有超过一定比例(默认50%)的请求被降级处理,Hystrix将会打开断路器,使该服务调用进入一个休眠期时间窗(默认5秒),随后断路器会进入半开状态,此时允许一定的服务调用通过,再次尝试进行连接,若这些请求都是健康的,则断路器会关闭;否则,断路器会再次进入休眠时间窗。(PS:当前请求次数未超过阈值时,无论前面的请求失败比例几何,都不出触发断路器。例如阈值Hystrix默认设置为20次,即使前面的19次请求都失败了,也不会触发断路器,但发起第20次请求后,Hystrix就会检查前面请求的失败比例是否超过设置比例,再来判断是否打开断路器。)
断路器有三个状态:Closed, Open, Half Open
Closed:所有请求都可以通过。
Open :所有请求都会被降级。
Half Open:允许一定的服务请求通过。
断路器阈值及休眠期时间设置如下
@HystrixCommand(commandProperties = { @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"), @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="10000") }) public String test(@PathVariable("id") Long id){ return restTemplate.getForObject("http://user-service/user/"+id,String.class); }

浙公网安备 33010602011771号