1. 程式人生 > 其它 >Spring Cloud Hystrix

Spring Cloud Hystrix

寫在前面

​ 在微服務架構中,通常會有多個服務間互相呼叫,如果某個服務不可用,導致多個服務故障,造成整個系統不可用的情況被稱為雪崩效應。Spring Cloud的防雪崩利器就是Hystrix,它是基於Netflix對應的Hystrix。

作用

  • 服務降級

    所謂的服務降級是指,在呼叫一方服務的時候沒有及時返回結果,或者呼叫失敗等情況出現以後,系統將自動採取另外一隻預備方案進行處理。優先核心服務,非核心服務不可用或弱可用。類似棄車保帥。

  • 服務熔斷

  • 依賴隔離

  • 監控(Hystrix Dashboard)

使用方式

RestTemplate的形式

通過HystrixCommand註解指定,並在fallbackMethod(回退函式)中具體實現降級邏輯

在pom.xml中引入依賴

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

在啟動類中加入註解@EnableCircuitBreaker,但是在@SpringCloudApplication中已經包含了這個註解,所以只引入@SpringCloudApplication即可

@EnableFeignClients
@SpringCloudApplication
public class OrderApplication {

   public static void main(String[] args) {
      SpringApplication.run(OrderApplication.class, args);
   }
}
import com.imooc.order.enums.ResultEnum;
import com.imooc.order.exception.OrderException;
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 = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
// })

    // @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"),  //錯誤率到達60%後觸發熔斷
// })
    @HystrixCommand(fallbackMethod = "fallback")
    @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("1661622"),
                String.class);
    }

    //不指定具體的降級方法,則會進入預設的降級方法
    @HystrixCommand
    @GetMapping("/getProductInfo")
    public String getProductInfo() {
        throw new OrderException(ResultEnum.ORDER_NOT_EXIST);
    }

    private String fallback() {
        return "太擁擠了, 請稍後再試~~";
    }

    private String defaultFallback() {
        return "預設提示:太擁擠了, 請稍後再試~~";
    }
}

以上也可通過配置檔案配置

hystrix:
  command:
    default: #預設超時時間配置
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000
    getProductInfoList: #指定方法配置超時時間,此處配置成方法名
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000

熔斷機制原理

上圖描述了斷路器模式設計狀態機,狀態機有三種狀態,closed(熔斷器關閉)、open(熔斷器開啟)、half open(熔斷器半開),當失敗次數累計到一定的閾值,或者說一定的比例就會啟動熔斷機制,熔斷器處於open狀態的時候,此時對服務都直接返回錯誤,但設計了一個時鐘選項,預設的時鐘到了一定時間就會進入半熔斷狀態,允許定量的服務請求,如果呼叫都成功,或者一定的比例成功,則認為服務恢復正常,就會關閉熔斷器,否則會認為依然服務異常,進入開啟模式。

//設定熔斷
@HystrixProperty(name = "circuitBreaker.enabled", value = "true")
//請求數達到後才計算(達到10次後計算錯誤率)
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10")
//休眠時間窗
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
//錯誤率到達60%後觸發熔斷
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")

feign-hystrix的使用

配置檔案中加入

feign:
  hystrix:
    enabled: true

feign介面中加入fallback屬性

import com.imooc.product.common.ProductInfoOutput;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;

//fallback用於配置回撥類
@FeignClient(name = "product", fallback = ProductClient.ProductClientFallback.class)
public interface ProductClient {

    @PostMapping("/product/listForOrder")
    List<ProductInfoOutput> listForOrder(@RequestBody List<String> productIdList);


    @Component
    static class ProductClientFallback implements ProductClient {

        @Override
        public List<ProductInfoOutput> listForOrder(List<String> productIdList) {
            return null;
        }

    }
}

熔斷控制檯

Spring Cloud Hystrix提供了一個控制檯,用於檢視系統熔斷情況

首先需要在pom.xml中加入依賴

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

在啟動類中加入@EnableHystrixDashboard

@EnableHystrixDashboard
@SpringCloudApplication
public class OrderApplication {

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

啟動應用,然後再瀏覽器中輸入http://localhost:8080/hystrix可以看到如下介面

Hystrix Dashboard共支援三種不同的監控方式

  • 預設的叢集監控:通過URL:http://turbine-hostname:port/turbine.stream開啟,實現對預設叢集的監控。

  • 指定的叢集監控:通過URL:http://turbine-hostname:port/turbine.stream?cluster=[clusterName]開啟,實現對clusterName叢集的監控。

  • 單體應用的監控:通過URL:http://hystrix-app:port/hystrix.stream開啟,實現對具體某個服務例項的監控。

  • Delay:控制伺服器上輪詢監控資訊的延遲時間,預設為2000毫秒,可以通過配置該屬性來降低客戶端的網路和CPU消耗。

  • Title:該引數可以展示合適的標題。

點選 Monitor Stream按鈕

  • 實心圓:

    1、通過顏色的變化代表了例項的健康程度,健康程度從綠色、黃色、橙色、紅色遞減。

    2、通過大小表示請求流量發生變化,流量越大該實心圓就越大。所以可以在大量的例項中快速發現故障例項和高壓例項。

  • 曲線:
    用來記錄2分鐘內流浪的相對變化,可以通過它來觀察流量的上升和下降趨勢。

注意:當使用Hystrix Board來監控Spring Cloud Zuul構建的API閘道器時,Thread Pool資訊會一直處於Loading狀態。這是由於Zuul預設會使用訊號量來實現隔離,只有通過Hystrix配置把隔離機制改成為執行緒池的方式才能夠得以展示。