天天看点

SpringCloud整合Hystrix熔断器

文章目录

      • SpringCloud整合Hystrix熔断器
        • 1、什么是Hystrix?
        • 2、服务调用雪崩
        • 3、线程隔离和服务降级
          • ①线程隔离原理
          • ②服务降级
        • 4、实现Hystrix服务降级★
          • ①导入springCloud的Hystrix依赖
          • ②注解启动类开启熔断
          • ③服务降级处理演示
            • 1>针对方法进行服务降级
            • 2>针对整个类进行服务降级
          • ④配置服务降级超时时间
        • 5、Hystrix服务熔断★
          • ①服务熔断原理
          • ②服务熔断模型
          • ③服务熔断处理演示

SpringCloud整合Hystrix熔断器

1、什么是Hystrix?

Hystrix是开源的延迟和容错库,用于隔离访问远程服务,第三方库,放置出现级联失败。

2、服务调用雪崩

微服务中,服务间的调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常复杂的调用链路,**一旦其中的某个服务出现问题,就会造成整个请求失败,调用的过程就会等待,请求阻塞,用户请求得不到响应,则tomcat的这个线程不会释放,于是越来越多的请求到来,就会有越来越多的请求阻塞。请求一直阻塞导致服务器资源耗尽。**这就是雪崩问题。

Hystrix使用服务降级解决雪崩问题。一旦某一个服务请求超时就进行服务降级,返回给用户一个类似网络拥堵的提示。

Hystrix解决雪崩问题主要就是服务降级,包括:

  • 线程隔离: 用户请求不直接访问服务,而是使用线程池中空闲的线程访问服务,加速访问失败判断的时间。
  • 服务降级: 及时返回服务调用失败的结果,让线程不因为等待服务而阻塞。

3、线程隔离和服务降级

①线程隔离原理

线程池中存在空闲的线程,就使用空闲的线程去访问服务,一旦线程耗尽,就直接返回拥堵状态。Hystrix为每个依赖调用分配一个小的线程池,如果线程池已满调用将立即被拒绝,默认不采用排队,加速失败的判断时间。

②服务降级

用户 请求故障时候,不会被阻塞,更不会无休止的等待或者看到系统崩溃,至少可以看到一个执行结果(例如返回预先设定好的提示信息)。

服务降级虽然会导致请求的失败,但是不会导致阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其他服务没有影响。

服务降级:有限保证核心服务,而非核心服务不可用或者弱可用。

服务降级的触发情况:

  • 线程池已满
  • 请求超时

4、实现Hystrix服务降级★

以下默认已经完成了eureka、feign,以及其他相关的业务操作。

示例为:ORDER服务远程调用PRODUCT服务进行服务降级。

①导入springCloud的Hystrix依赖
<!--Hystrix依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <!--在同一版本管理中,版本号可以不写-->
    <version>2.1.5.RELEASE</version>
</dependency>
           
②注解启动类开启熔断
/**
 *@SpringCloudApplication注解==>
 *      @EnableCircuitBreaker:开启熔断
 *      @SpringBootApplication:声明启动类
 *      @EnableDiscoveryClien:声明Eureka客户端
 */
@EnableFeignClients  //声明这是一个EnableFeignClients的客户端,必须要有
@EnableDiscoveryClient  //声明这是一个Eureka客户端
@SpringBootApplication
@EnableCircuitBreaker   //开启Hystrix的熔断
//@SpringCloudApplication
public class UdaiOrderApplication {

    public static void main(String[] args) {
  SpringApplication.run(UdaiOrderApplication.class, args);
    }

}
           
③服务降级处理演示

1>针对方法进行服务降级

ORDER服务:

@RestController
@RequestMapping("order")
public class OrderController {

    @Autowired
    private ProductControllerApi productControllerApi;

    /**
     * 订单中查询商品信息,调用商品服务。
     * @param productId
     * @return
     */
    @RequestMapping("getProductInfoById")
    @HystrixCommand(fallbackMethod = "hystrixFallback")  //注解设置服务降级的回调方法
    public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
        System.out.println("进入ORDER服务,getProductFromProduct" + productId);
        return productControllerApi.getProductInfoById(productId);
    }
    /**
     * 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
     * @return
     */
    public JsonBean hystrixFallback(Integer productId) {
        return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
    }
}
           

1、方法服务降级是在调用的接口上面加上注解@HystrixCommand(fallbackMethod = “hystrixFallback”)并指定fallbackMethod 参数值,去实现这个方法。

2、服务降级的方法必须同调用的接口有相同的参数以及返回值。

当前接口服务降级结果:

SpringCloud整合Hystrix熔断器

2>针对整个类进行服务降级

ORDER服务全局默认降级:

@RestController
@RequestMapping("order")
@DefaultProperties(defaultFallback = "defaultFallback")  //默认服务降级调用的方法
public class OrderController {

    @Autowired
    private ProductControllerApi productControllerApi;

    /**
     * 订单中查询商品信息,调用商品服务。
     *
     * @param productId
     * @return
     */
    @RequestMapping("getProductInfoById")
    //@HystrixCommand(fallbackMethod = "hystrixFallback")  //注解设置服务降级的回调方法
    @HystrixCommand
    public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
        System.out.println("进入ORDER服务,getProductFromProduct" + productId);
        return productControllerApi.getProductInfoById(productId);
    }

    /**
     * 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
     *
     * @return
     */
    public JsonBean hystrixFallback(Integer productId) {
        return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
    }

    /**
     * 默认服务降级
     * @return
     */
    public JsonBean defaultFallback() {
        return new JsonBean(0, "默认温馨提示:网络拥堵,请稍后再试", null);
        //return "温馨提示:网络拥堵,请稍后再试";   //返回类型必须和方法一致
    }
}
           

1、全局服务降级,是在类上面加注解@DefaultProperties(defaultFallback = “defaultFallback”),并指定defaultFallback 参数的值,去在当前类实现这个方法。并在需要降级的方法上面加上注解@HystrixCommand不配置任何参数。

2、与方法上面的降级不同的是,这个默认降级不需要参数,但是需要相同的返回值类型。

当前接口使用全局服务降级结果:

SpringCloud整合Hystrix熔断器
④配置服务降级超时时间

不配置服务降级时间的话,Hystrix默认服务降级时间是一秒,时间太短了,需要在yml文件里面进行配置或者在注解中进行配置。

#此项内容也可以通过注解去设置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000  #服务降级时间2秒
           

5、Hystrix服务熔断★

①服务熔断原理

在服务熔断中,使用熔断器,也叫作断路器(Circuit Breaker)。

Hystrix熔断的机制类似于电路短路熔断保护。在分布式系统应用中应用服务熔断后,服务可以自行判断哪些服务反应慢或者存在大量超市,可以针对这些服务进行熔断防止拖垮整个系统。

②服务熔断模型
SpringCloud整合Hystrix熔断器
  • Closed:

    熔断器关闭状态。

  • Open:

    熔断器打开转态。当失败请求达到阈值服务降级。

    阈值:服务失败达到一定的值是,断路器将会打开。请求的次数最少不低于20次,当失败的请求占比50%,断路器打开。

  • Half Open:

    熔断器半开,允许部分请求进行访问。熔断器打开后,休眠五秒(默认)进行半开,如果再次失败仍然会打开熔断器,成功后会关闭熔断器。

③服务熔断处理演示

模拟某一个请求是错误的,导致整个服务都降级请求不了:

请求getProductInfoById方法,productId=2,多次请求导致服务降级。导致其他成功的服务也随之降级。

http://localhost:8080/order/getProductInfoById?productId=2

@RestController
@RequestMapping("order")
@DefaultProperties(defaultFallback = "defaultFallback")  //默认服务降级调用的方法
public class OrderController {

    @Autowired
    private ProductControllerApi productControllerApi;

    /**
     * 订单中查询商品信息,调用商品服务。
     *
     * @param productId
     * @return
     */
    @RequestMapping("getProductInfoById")
    //@HystrixCommand(fallbackMethod = "hystrixFallback")  //注解设置服务降级的回调方法
    @HystrixCommand
    public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
        //模拟某一个请求是错误的,导致整个服务都降级请求不了
        if(productId == 2){
          throw new RuntimeException("熔断测试");
        }
        System.out.println("进入ORDER服务,getProductFromProduct" + productId);
        return productControllerApi.getProductInfoById(productId);
    }

    /**
     * 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
     *
     * @return
     */
    public JsonBean hystrixFallback(Integer productId) {
        return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
    }

    /**
     * 默认服务降级
     * @return
     */
    public JsonBean defaultFallback() {
        return new JsonBean(0, "默认温馨提示:网络拥堵,请稍后再试", null);
        //return "温馨提示:网络拥堵,请稍后再试";
    }
}
           

productId=1成功的服务:

请求getProductInfoById方法,productId=1。

http://localhost:8080/order/getProductInfoById?productId=1

SpringCloud整合Hystrix熔断器

多次请求productId=2失败,导致productId=1服务降级:

SpringCloud整合Hystrix熔断器

修改服务熔断的默认配置:

#此项内容也可以通过注解去设置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000  #服务降级时间2秒
      circuitBreaker:
        errorThresholdPercentage: 50  #触发熔断错误比例阈值,默认50%
        sleepWindowInMilliseconds: 10000  #熔断后休眠时长,默认5秒
        requestVolumeThreshold: 10  #熔断触发最小请求次数,默认值是20,修改为10