SpringCloud Netflix Hystrix
一、雪崩效应
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,
这就是所谓的"扇出”、如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。
对于高流量的应用来说,单- -的后端依赖可能会导致所有服务器上的所有资源都在几秒中内饱和。比失败更糟的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
我们需要:弃车保帅:
二、Hystrix概念
Hystrix是一个用于处理分布式系统的延迟和容错的开源库, 在分布式系统里,许多依赖不可避免的会调用 失败,比如超时,异常等,Hystrix能够保证在一 个依赖出问题的情况下, 不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
三、Hystrix的断路机制
1、线程池隔离(默认)
服务的调用者(消费者)会从Hystrix线程池中申请一个线程帮助自己访问服务,服务调用者的线程会阻塞住,等着线程池中的线程反馈结果,当服务器宕机,线程池的线程响应超时时,该线程池的线程就被全部被申请完,此时就拒绝访问该服务器
2、信号量隔离
每个前线程去访问服务会有标记,这个服务每访问一次会加1,服务访问成功会减一,如果这个值超过10就不让访问这个服务,请求就被拦截下来。
3、降级服务
当需要调用的微服务出现问题时,默认会去调用一个本地降级方法,降级方法会返回错误信息或者一个合理的默认值,从而继续后面的业务,线程不会阻塞在哪里。
4、熔断器
在微服务的访问过程中,如果大量的请求访问超时或者失败,则熔断器就会自动打开,如果熔断器打开之后,后续所有访问这个微服务的请求,会立刻被通知失败。熔断器开启后,会每隔一段时间进入半开状态,半开状态下,会释放一个服务尝试请求资源,如果请求成功,则熔断器就会 关闭,反之又会回到半开的状态。
Ribbon整合Hystrix
1、导入hystrix核心依赖,还要导入eureka(传递依赖了ribbon)的依赖
<!--hystrix核心依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2、编写本地降级方法,接口使用@HystrixComman并指定对应方法
@RestController public class HystrixTestController { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "helloHystrix")//表示服务降级调用本地的helloHystrix方法 @RequestMapping("/hello") public String hello(){ String forObject = restTemplate.getForObject("http://RIBBON-PROVIDER/provider/hello?msg=123", String.class); return forObject; } //本地降级方法 public String helloHystrix(){ return "【hystrix】:调用的服务器异常......"; } }
3、主启动类添加@EnableHystrix开启服务降级注解
注:@EnableHystrix与@EnableCircuitBreaker的作用是一样的,@EnableHystrix继承了@EnableCricuitBreaker,可读性更好。
@SpringBootApplication @ComponentScan("com.jn") @EnableEurekaClient @EnableHystrix//表示开启服务降级功能 public class Day0213SpringcloudHystrixRibbonApplication { public static void main(String[] args) { SpringApplication.run(Day0213SpringcloudHystrixRibbonApplication.class, args); } @Bean @LoadBalanced//开启负载均衡 public RestTemplate restTemplate(){ return new RestTemplate(); } }