SpringCloud (x) Avalanche service and fuse Hystrix

 

 

 

 

@author QYX Since learning many tasks, handling recently suspended for a few days, two days after recovery

Introduction of fuse Hystrix

 

 

 

It is simple, in a distributed system, if there is a need to request service call A, but A service there is a problem, it will block the request, then the request will be blocked as long as the call to service A, when the request increasingly blocked the more computer resource usage on more and more. Furthermore, the service is a problem that could cause all requests are unavailable, causing the entire distributed system is not available, this is the "avalanche effect."

Avalanche effect common scenario

  • Hardware failure: If the server is down, room power, fiber Waduan like.

  • A surge in traffic: such as abnormal traffic, retry increase traffic.

  • Cache Penetration: generally occurs in the application restart, when all of a cache miss, and a short time when a large number of cache invalidation. A lot of cache miss, the request Watch back-end services, resulting in a service provider overloaded, causing service is unavailable.

  • Program BUG: The program logic causes a memory leak, JVM long FullGC like.

  • Synchronization wait: synchronous mode between calls using the service, resource depletion caused by synchronization wait.

Avalanche Strategies

For different scenarios caused by the avalanche effect, you can use different tactics, not a strategy common to all scenarios, refer to the following:

  • Hardware failure: Multi-room disaster recovery, remote live and so on.

  • A surge in traffic: automatic service expansion, flow control (limiting, closed retry) and the like.

  • Cache penetration: Cache preloading, caching asynchronous loading and so on.

  • Program BUG: modify the program bug, timely release of resources.

  • Synchronization wait: resource isolation, MQ decoupling, unavailable service call fails and so fast. Resource isolation generally refers to the different service calls using different thread pool; not to fail fast with the service call is usually through a combination of fuse mode timeout mechanism.

In summary, if an application can not isolate the fault from dependence, and that the application itself is at risk of collapse. Therefore, in order to build a stable, reliable distributed systems, our service should have the ability to protect themselves when the dependent services are not available, the current service to start self-protection, so as to avoid the avalanche effect occurs. This article focuses on the use of avalanche Hystrix solve the problem of synchronization wait.

Service Isolation

Service downgraded

Hystrix:

Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。为了实现容错和自我保护,下面我们看看Hystrix如何设计和实现的。

Hystrix设计目标:

  • 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的

  • 阻止故障的连锁反应

  • 快速失败并迅速恢复

  • 回退并优雅降级

  • 提供近实时的监控与告警

Hystrix遵循的设计原则:

  • 防止任何单独的依赖耗尽资源(线程)

  • 过载立即切断并快速失败,防止排队

  • 尽可能提供回退以保护用户免受故障

  • 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响

  • 通过近实时的指标,监控和告警,确保故障被及时发现

  • 通过动态修改配置属性,确保故障及时恢复

  • 防止整个依赖客户端执行失败,而不仅仅是网络通信

Hystrix如何实现这些设计目标?

  • 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行;

  • 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。

  • 记录请求成功,失败,超时和线程拒绝。

  • 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。

  • 请求失败,被拒绝,超时或熔断时执行降级逻辑。

  • 近实时地监控指标和配置的修改。

Hystrix组件

 

 

 

对RestTemplate的支持

引入hystrix的依赖

order_service

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

 

 

在启动类中激活Hystrix

order_service

 package qqq;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 import org.springframework.context.annotation.Bean;
 import org.springframework.web.client.RestTemplate;
 
 @SpringBootApplication
 @EntityScan("com.qqq.entity")
 //@EnableFeignClients
 //激活hystrix
 @EnableCircuitBreaker
 public class OrderApplication {
     public static void main(String[] args) {
         SpringApplication.run(OrderApplication.class,args);
    }
     /**
      * eureka和consul都集成了Ribbon
      * 使用spring提供的RestTemplate发送http请求到商品服务
      * 1 将RestTemplate对象交给容器管理
      * 2 使用其方法完成操作
      */
     @LoadBalanced //Ribbon自带的负载均衡的注解
     @Bean
     public RestTemplate restTemplate()
    {
         return new RestTemplate();
    }
 
 
 }
 

配置熔断触发的降级逻辑

在order_service的controller中配置

    /**
      * 降级方法
      * 和需要收到保护的方法的返回值一致
      * 接口参数一致
      */
     public Product orderFallBack(Long id)
    {
         Product product=new Product();
         product.setProductName("触发降级方法");
         return product;
    }

在需要受到保护的接口上使用@HystrixCommand配置

     @HystrixCommand(fallbackMethod = "orderFallBack")
     @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
     public Product findById(@PathVariable("id") Long id)
    {
         Product product=null;
         product=productFeginClient.findById(id);
         return product;
    }

注意事项:

在之前的案例中,请求在超过1秒后都会返回错误信息,这是因为Hystrix的默认超时时长为1,我们可以通过配置修改这个值:

 hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMillisconds: 3000 #默认的连接超时为1s,如果1s没有返回数据,hystrix会自动触发降级逻辑

配置统一的降级方法:

 package com.qqq.controller;
 
 import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
 import com.qqq.entity.Product;
 import com.qqq.fegin.ProductFeginClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cloud.client.ServiceInstance;
 import org.springframework.cloud.client.discovery.DiscoveryClient;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 
 import java.util.List;
 
 @RestController
 @RequestMapping("/order")
 /**
  * 指定公共的属性
  * 如果过在@DefaultProperties指定了公共的降级方法
  * 在@HystrixCommand不需要单独指定了
  *
  */
 @DefaultProperties(defaultFallback = "defaultFallBack")
 public class OrderController {
    //注入RestTemplate对象
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ProductFeginClient productFeginClient;
    /**
      * 使用注解配置熔断保护
      * fallbackmethod:配置熔断之后的降级方法
      * @param id
      * @return
      */
    @HystrixCommand
    @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
    public Product findById(@PathVariable("id") Long id)
    {
        Product product=null;
        product=productFeginClient.findById(id);
        return product;
    }
    /**
      * 降级方法
      * 和需要收到保护的方法的返回值一致
      * 接口参数一致
      */
    public Product orderFallBack(Long id)
    {
        Product product=new Product();
        product.setProductName("触发降级方法");
        return product;
    }
    public Product defaultFallBack()
    {
        Product product=new Product();
        product.setProductName("触发统一的降级方法");
        return product;
    }
 }
 

 

Guess you like

Origin www.cnblogs.com/qyx66/p/12355310.html