天天看点

SpringCloud - Hystrix(三)

Hystrix 服务熔断
SpringCloud - Hystrix(三)
SpringCloud - Hystrix(三)
SpringCloud - Hystrix(三)
  • 容错机制:微服务和分布式里面,容错是必须要考虑的!通常的做法有两种
  • 一种是重试机制,对于预期的短暂故障问题,可以重试解决;
  • 二是使用断路器模式,即将受保护的服务封装到一个可以监控故障的断路器里面,当故障达到一定的值,断路器将会跳闸,断路器对象返回错误!

断路器状态机: 1.closed,熔断器关闭状态,调用失败次数累计到一定阈值/比例,启动熔断机制,进入打开状态 2.open,熔断器打开状态,对服务直接返回错误,直接服务降级 3.half open,熔断器打开状态达到了一定的时间,会进入半熔断状态,允许定量的服务请求主逻辑。如果都调用成功,或者一定比例成功,则认为恢复,关闭熔断器;否则,熔断器回到打开状态

断路器模式设计状态机(三种状态)

  • Closed(熔断器的关闭状态):熔断器关闭状态,调用失败次数累计到一定阈值/比例,启动熔断机制,进入打开状态
  • Open(熔断器打开状态):熔断器打开状态,对服务直接返回错误,直接服务降级
  • Half Open(熔断器半熔断状态):熔断器打开状态达到了一定的时间,会进入半熔断状态,允许定量的服务请求主逻辑。如果都调用成功,或者一定比例成功,则认为恢复,关闭熔断器;否则,熔断器回到打开状态
  • sleepWindowInMilliseconds:休眠时间窗口
  • requestVolumeThreshold:最小的请求数
  • errorThresholdPercentage:服务错误百分比(比如百分之70,就是10个请求,有7个错误)

Product 微服务项目

@PostMapping("/listForOrder")
public List<ProductInfoOutput> listForOrder(@RequestBody List<String> productIdList) {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return productService.findList(productIdList);
}      

Order 微服务项目

package com.imooc.order.controller;
 
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
 
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
 
  @HystrixCommand(commandProperties = {
      @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),          //设置熔断
      @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 请求数达到后才计算
      @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 熔断时间
      @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), // 错误率
  })
  @GetMapping("/getProductInfoList")
  public String getProductInfoList(@RequestParam("number") Integer number) {
    if (number % 2 == 0) {
      return "success";
    }

    RestTemplate restTemplate = new RestTemplate();
    return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder",
        Arrays.asList("157875196366160022"),
        String.class);
  }
 
  private String defaultFallback() {
    return "默认提示:太拥挤了, 请稍后再试~~";
  }
}      
  • 此时默认 1s(为了达到降级效果),这里模拟了一个奇数偶数判断是为了模拟熔断的场景。

继续阅读