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配置把隔離機制改成為執行緒池的方式才能夠得以展示。