雪崩问题:
用户的一个请求,需要若干个服务完成才能响应,若一个服务未发生相应,则会卡在这,导致请求未响应,同时也会占用服务器的连接数。
Hustrix解决雪崩问题的方法:
1)线程隔离
不同的服务请求,用不同的线程池隔离。尽管线程池占满们也只是部分资源。
2)服务熔断。降级。
当线程池拍满以后,线程池设置时间,超时之后,服务降级,返回错误信息。保护优先服务。
使用:
1)导入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> hystrix: # command: # default: # execution: # isolation: # thread: # timeoutInMilliseconds: 3000 #全局延迟时间,超过后熔断降级 # user-service: #针对某个服务或方法 # execution: # isolation: # thread: # timeoutInMilliseconds: 3000
2)家注解在启动类上
//@EnableCircuitBreaker //熔断 //@EnableDiscoveryClient//服务客户端 //@SpringBootApplication @SpringCloudApplication public class ConsumerApplication { @Bean @LoadBalanced //底层用了拦截器,拦截restTemplate 的http请求,使用负载均衡算法处理请求 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class); } }
3)编写降级逻辑
@RestController @RequestMapping("consumer/pojo") @DefaultProperties(defaultFallback = "defaultFallback") //默认fallback public class ConsumerController { @Autowired private RestTemplate restTemplate; //@Autowired //private RibbonLoadBalancerClient client; @GetMapping("{id}") @HystrixCommand(commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")//自定义超时时间。 })// 开启降级处理在该方法上 public String queryById(@PathVariable("id")Integer id){ String url="http://user-service/user/"+id; String user=restTemplate.getForObject(url,String.class); return user; } public String queryByIdFall(Integer id){ return "繁忙"; } public String defaultFallback(){ return "繁忙!!!"; } }
三种状态的转换:
closed->open:正常情况下熔断器为closed状态,当访问同一个接口次数超过设定阈值并且错误比例超过设置错误阈值时候,就会打开熔断机制,这时候熔断器状态从closed->open。
open->half-open:当服务接口对应的熔断器状态为open状态时候,所有服务调用方调用该服务方法时候都是执行本地降级方法,那么什么时候才会恢复到远程调用那?Hystrix提供了一种测试策略,也就是设置了一个时间窗口,从熔断器状态变为open状态开始的一个时间窗口内,调用该服务接口时候都委托服务降级方法进行执行。如果时间超过了时间窗口,则把熔断状态从open->half-open,这时候服务调用方调用服务接口时候,就可以发起远程调用而不再使用本地降级接口,如果发起远程调用还是失败,则重新设置熔断器状态为open状态,从新记录时间窗口开始时间。
half-open->closed: 当熔断器状态为half-open,这时候服务调用方调用服务接口时候,就可以发起远程调用而不再使用本地降级接口,如果发起远程调用成功,则重新设置熔断器状态为closed状态。
当请求在规定时间内响应正常,熔断器处于关闭状态。
如果有超过50%的请求失败,即达到阈值,则触发熔断(请求次数最少不低于10次),处于open状态。
close状态不是永久的,关闭后会进入休眠时间默认是5s,随后会进入半开状态,此时,会释放部分请求通过,若这些请求是健康的,则会完全关闭断路器,否则继续保持关闭,再次进入休眠。
默认时长为1s