功能
- 服務降級
- 優先核心服務,非核心服務弱可用或不可用
- 具體表現爲當調用一個服務不可用或者發生異常時,轉到指定降級頁面或觸發降級信息
- 通過@HystrixCommand註解指定
- fallackMethod(回退函數)中實現降級的邏輯
- 目標服務不可用--降級
- 本服務出現異常(比如數據庫連接過多,或訪問量太大)--也可以選擇降級
- 服務熔斷
- 某個服務的錯誤率到達一定閾值,切斷服務
- 當斷路器打開,而服務不可用時,休眠時間窗就開始計時,計時結束後,將熔斷器設爲半打開,嘗試發一次請求,若請求成功,關閉熔斷器;若失敗,休眠時間窗繼續計時
- 依賴隔離
- 爲每個方法設立一個線程池用於隔離
- 監控(Hystrix Dashboard)
集成
pom引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
啓動類添加註解
@EnableCircuitBreaker
服務降級
A服務訪問B服務,B服務不可用時,觸發降級,轉到某靜態頁面如提示"太擁擠了,請稍後再試"
新建 HystrixController 測試
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@RestController
public class HystrixController {
//超時配置
@HystrixCommand(fallbackMethod = "fallback") //回調方法名
@GetMapping("/getProductInfoList")
public String getProductInfoList() {
//使用RestTemplate 調用其他服務方法名
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String fallback() {
return "太擁擠了, 請稍後再試~~";
}
}
也可以指定默認方法
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
//超時配置
@HystrixCommand
@GetMapping("/getProductInfoList")
public String getProductInfoList() {
//使用RestTemplate 調用其他服務方法名
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String defaultFallback() {
return "默認提示:太擁擠了, 請稍後再試~~";
}
}
超時時間配置
默認超時時間是1秒,即在一秒鐘之內無法收到返回的結果就會降級。而許多服務的運行時間確實長,所以需要更改超時時間
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
使用配置項設置
在方法加註解@HystrixCommand的前提下,配置文件中配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
getProductInfoList:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
可使用default統一設置,也可以爲具體的方法具體設置,如getProductInfoList
feign-hystrix的使用
配置添加
feign:
hystrix:
enabled: true
啓動類添加掃描使Feign的包被掃描到
@ComponentScan(basePackages = "com.viki")
Feignclient的配置更改
@FeignClient(name = "product", fallback = ProductClient.ProductClientFallback.class)
public interface ProductClient {
@PostMapping("/product/listForOrder")
List<ProductInfoOutput> listForOrder(@RequestBody List<String> productIdList);
@PostMapping("/product/decreaseStock")
void decreaseStock(@RequestBody List<DecreaseStockInput> decreaseStockInputList);
//降級回調函數
@Component
static class ProductClientFallback implements ProductClient{
@Override
public List<ProductInfoOutput> listForOrder(List<String> productIdList) {
return null;
}
@Override
public void decreaseStock(List<DecreaseStockInput> decreaseStockInputList) {
}
}
}
依賴隔離
Hystrix使用倉壁模式實現了線程池的隔離,會爲每個HystrixCommand創建一個獨立的線程池,各HystrixCommand之前互相隔離,不會相互影響,自動實現依賴隔離。
服務降級和依賴隔離是一體化實現的
服務熔斷
@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") //失敗率,高於此則打開斷路器
})
主要有4個參數,以上都有註釋
整體的效果是:在10秒鐘之內,若請求數大於等於10次,其中失敗率達到60%,即失敗超過6次,熔斷器就會開啓。此時就會觸發降級。
10秒鐘結束後,自動發一次請求,若成功,則關閉熔斷器,請求會正常;若失敗,熔斷器保持打開,服務降級。
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@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:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String defaultFallback() {
return "默認提示:太擁擠了, 請稍後再試~~";
}
}
請求必須攜帶number參數,若number爲偶數,就直接訪問成功,顯示爲success;若number爲奇數,就調用服務,此時服務未啓動,便失敗觸發降級。
http://localhost:8081/getProductInfoList?number=1 失敗
http://localhost:8081/getProductInfoList?number=2 成功
不斷訪問失敗鏈接,一直快速訪問。此時在訪問成功鏈接,也出現了降級,失敗
Dashboard界面查看熔斷
pom引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
啓動類添加註解
@EnableHystrixDashboard
打開上方提到的熔斷器,啓動項目後網頁輸入 http://localhost:8081/hystrix
URL輸入 http://localhost:8081/actuator/hystrix.stream
Delay延時設置爲2000
Title應用名稱設置爲Order
點擊Monitor Stream
此時訪問上述兩個鏈接之一纔會顯示儀表盤