推薦:微服務彙總
Spring Cloud 之Hystrix熔斷器、Hystrix-Dashboard可視化監控中心
為了大家能更好的了解Hystrix原理,可以讀一下這篇部落格:Hystrix原理
在之前的部落格中,我介紹了Hystrix的基本使用:Spring Cloud 之Hystrix初使用
是以這裡有一些重複且不相關的代碼就不寫了,比如注冊中心,Server服務的
pom.xml
和
application.yml
、Client服務的
pom.xml
、
application.yml
以及RestTemplate元件。
Server服務的getMessage接口:
package com.kaven.server.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MessageServerController {
@GetMapping("/getMessage")
public String getMessage(){
System.out.println("進來了");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2000ms後又開始了");
return "hello , Jack";
}
}
Thread.sleep(2000);
的原因是想模拟請求服務逾時,進而導緻請求錯誤率達到進入熔斷器打開的門檻值。
Client服務的getMessage接口:
package com.kaven.client.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.beans.factory.annotation.Autowired;
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;
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class MessageController{
@Autowired
private RestTemplate restTemplate;
@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("/getMessage")
public String getMessage(@RequestParam("flag") Integer flag){
if(flag % 2 == 0){
String message = restTemplate.getForObject("http://server/getMessage" , String.class);
return "get: "+message;
}
else{
return "success";
}
}
public String defaultFallback(){
return "error";
}
}
flag
參數的作用是用來控制請求錯誤與成功的占比,友善示範熔斷器的狀态。
關鍵是下面這四個屬性配置。
@HystrixProperty(name = "circuitBreaker.enabled" , value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold" , value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds" , value = "10000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" , value = "60")
熔斷器配置
Circuit Breaker
主要包括如下6個參數:
-
:是否啟用熔斷器,預設是TRUE。circuitBreaker.enabled
-
:熔斷器強制打開,始終保持打開狀态,不關注熔斷開關的實際狀态。預設值FLASE。circuitBreaker.forceOpen
-
:熔斷器強制關閉,始終保持關閉狀态,不關注熔斷開關的實際狀态。預設值FLASE。circuitBreaker.forceClosed
-
:錯誤率門檻值,預設值50%,例如一段時間(10s)内有100個請求,其中有54個逾時或者異常,那麼這段時間内的錯誤率是54%,大于了預設值50%,這種情況下會觸發熔斷器打開。circuitBreaker.errorThresholdPercentage
-
:預設值20。含義是一段時間内至少有20個請求才進行circuitBreaker.requestVolumeThreshold
計算。比如一段時間有19個請求,且這些請求全部失敗了,錯誤率是100%,但熔斷器不會打開,總請求數不滿足20。errorThresholdPercentage
-
:半開狀态試探睡眠時間,預設值5000ms。如:當熔斷器開啟5000ms之後,會嘗試放過去一部分流量進行試探,确定依賴服務是否恢複。circuitBreaker.sleepWindowInMilliseconds
源碼中的預設值:
private static final Boolean default_circuitBreakerEnabled = true;
private static final Integer default_circuitBreakerRequestVolumeThreshold = 20;// default => statisticalWindowVolumeThreshold: 20 requests in 10 seconds must occur before statistics matter
private static final Integer default_circuitBreakerSleepWindowInMilliseconds = 5000;// default => sleepWindow: 5000 = 5 seconds that we will sleep before trying again after tripping the circuit
private static final Integer default_circuitBreakerErrorThresholdPercentage = 50;// default => errorThresholdPercentage = 50 = if 50%+ of requests in 10 seconds are failures or latent then we will trip the circuit
private static final Boolean default_circuitBreakerForceOpen = false;// default => forceCircuitOpen = false (we want to allow traffic)
/* package */ static final Boolean default_circuitBreakerForceClosed = false;// default => ignoreErrors = false
代碼都寫好了,接下來要示範熔斷器的各種狀态,為了可視化熔斷器的狀态,這裡還要介紹Hystrix-Dashboard。
Client服務還需要加入如下依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Hystrix-Dashboard是通過浏覽器請求固定接口來通路的,是以這裡直接暴露所有的端點(接口):
management:
endpoints:
web:
exposure:
include: '*'
通路
http://localhost:8002/hystrix
,可以得到如下圖所示的界面,填入相關資訊即可。
點選
Monitor Stream
,可以得到如下圖所示的界面。
接下來我們使用Postman來進行示範,不會有人去瘋狂點吧(滑稽),大家按下面圖示跟着操作即可。
這裡直接請求100次,前面幾次執行會慢一些,請求到達十次之後就執行非常快了,這是為什麼呢?因為一段時間内至少有10個請求才進行
errorThresholdPercentage
計算(
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold" , value = "10")
),是以,即使前幾次請求錯誤率是100%,熔斷器也不會打開,當請求到達十次,滿足了
requestVolumeThreshold
,并且錯誤率是100%,熔斷器就打開了,其實錯誤率達到60%就可以了(
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" , value = "60")
);這樣後續的請求,會快速傳回,這就是為什麼當請求到達十次之後執行會非常快的原因。
錯誤率100%,熔斷器打開了。
等10秒(
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds" , value = "10000")
),之後熔斷器嘗試半開(其實在Dashboard上還是會顯示open狀态),放入一部分流量請求進來,相當于對依賴服務進行一次健康檢查,如果請求成功,熔斷器關閉,我們來示範請求成功到底會不會導緻熔斷器關閉。
請求
http://127.0.0.1:8002/getMessage?flag=1
很顯然會成功。
熔斷器确實關閉。