zoukankan      html  css  js  c++  java
  • springcloud之Hystrix实现容错处理

    如果服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,知道提供者响应或超时,在高负载场景下,如果不做任何处理,那么就会导致服务消费者的资源耗尽甚至整个系统崩溃。微服务架构的应用系统通常包含多个服务层,微服务之间通过网络进行通信,从而支撑起整个应用系统,服务之间难免存在依赖关系,事实上,微服务并非总是能够保持可用状态,而网络也往往非常脆弱,因此难免有些请求会失败。

      我们把“基础服务故障”而导致“级联故障”的现象称为雪崩效应。雪崩效应描述的是提供者不可用导致消费者不可用,并将不可用逐渐传递放大的过程。

      要想防止雪崩效应,必须有一个强大的容错机制,它应该实现以下两点:

    1. 为网络请求设置超时:通常情况下,一次远程调用对应着一个线程/进程,如果响应太慢,这个线程/进程就得不到释放,进而导致系统资源耗尽,最终导致服务不可用 。
    2. 使用断路器模式:就比如家里如果没有断路器,当电流过载时(功率过大、短路等),电路没有断开,电路就会迅速发热,烧断电路甚至引起火灾,使用断路器之后,一旦电流过载就会跳闸切断电路,从而保护电路安全。同理,如果某个微服务的请求大量超时了,再去产生新的请求已经没有任何意义,只会白白消耗资源。微服务里断路器可以理解为对容易导致错误的操作的一个代理。这种代理能够统计一段时间内调用失败的次数,并决定是正常请求依赖的服务还是直接返回。断路器可以快速失败,如果它在一段时间内检测到许多类似的错误,就会在之后的一段时间内,强迫对该服务的调用失败,不再请求所依赖的服务,这样就减少了cpu的超时等待时间。断路器也可以自动诊断依赖的服务是否已经恢复正常,这样,微服务就有了“自我修复”的功能:当依赖的服务不正常时开启快速失败机制,防止雪崩效应;当发现服务恢复正常时,又会恢复请求。

      Hystrix就是spring cloud中一个断路器,它是由Netflix开源的一个延迟和容错库,用于隔离远程系统,服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错:

    • 包裹请求:使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立线程中执行(这里用了“命令模式”)
    • 跳闸机制:当某个服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止该服务的请求一段时间
    • 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就会被立即拒绝,而不是排队等候,加速失败判定
    • 监控:Hystrix可以近乎实时的监控运行指标和配置的变化,例如成功或失败等
    • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。这个可以由开发人员自行提供
    • 自我修复:断路器打开一段时间后,会自动进入“半开”状态(探测服务是否可用,如还是不可用,再次退回打开状态)。

    在Ribbon中使用Hystrix:

      添加maven依赖:

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
     </dependency>

    在程序的启动类ServiceRibbonApplication 加@EnableHystrix注解开启Hystrix:

    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    @EnableHystrix
    public class ServiceRibbonApplication {
    
        public static void main(String[] args) {
            SpringApplication.run( ServiceRibbonApplication.class, args );
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

    在service方法中添加@HystrixCommand注解,开启熔断功能,并指定回退方法fallbackMethod ,进行快速失败操作:

    @Service
    public class HelloService {
    
        @Autowired
        RestTemplate restTemplate;
    
        @HystrixCommand(fallbackMethod = "hiError")
        public String hiService(String name) {
            return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
        }
    
        public String hiError(String name) {
            return "hi,"+name+",sorry,error!";
        }
    
    }

    在Feign中使用熔断器

      在配置文件中打开:feign.hystrix.enabled=true

      在FeignClient注解的接口方法上,增加了fallback指定类:

    @FeignClient(value = "service-hi",fallback = SchedualServiceHiHystric.class)
    public interface SchedualServiceHi {
        @RequestMapping(value = "/hi",method = RequestMethod.GET)
        String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }

    然后实现该类和方法即可。这里的fallback方法执行并不代表断路器已经打开,请求失败、超时、被拒绝等情况下都会执行回退逻辑。

    Hystrix线程隔离与传播上下文:

      线程隔离的策略分两种:分别是线程隔离和信号量隔离。线程隔离表示HystrixCommand将会在单独的线程上执行,并发请求受线程池中线程数量的限制;信号量隔离是指HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受信号量个数限制。Hystrix默认并推荐使用线程隔离模式,因为这种方式有除了网络超时以外的额外保护层,只有在调用负载非常高时才需要使用信号量,可以减少线程开销。

  • 相关阅读:
    真爱 vs. 种姓:新一代印度人的婚恋观
    美国司法部解禁guns打印技术
    特朗普访英,吃瓜群众却只想看《真爱至上》
    Semaphore(信号量)
    RLock(递归锁)
    用python编写九九乘法表
    php传值和传引用的区别
    post请求的header
    Content-type详解
    thinkphp5 学习笔记
  • 原文地址:https://www.cnblogs.com/loveBolin/p/9903745.html
Copyright © 2011-2022 走看看