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)的依赖


        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        

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();
    }
}