1. 程式人生 > >Spring Cloud(五) :斷路器(Hystrix)

Spring Cloud(五) :斷路器(Hystrix)

Hystrix是一款Netflix開源的熔斷中介軟體,能夠提供斷路,降級,監控等多種服務。
就如我們日常生活中的電路保險絲,當接入電源的電器過多,導致整體負載過大時,保險絲會自動熔斷,以此保護電器不會受損。
而在微服務架構中,當一個服務介面不堪重負,出現超時或宕機等無法使用的情況時,下游服務因獲取不到資料,導致服務不可用,然後惡性迴圈導致整個服務體系宕機,形成雪崩效應。此時熔斷器就充當了保險絲的作用,在服務介面超時或不可用時,馬上返回一個錯誤資訊,讓整個服務可以繼續執行,保護了整個服務體系。

PS:本文Spring Boot為2.X版本

程式碼下載

這裡將會在上一篇Spring Cloud(四) :微服務間的互相呼叫和負載均衡實現(ribbon+restTemplate和feign)

的基礎上進一步擴充套件。
用到的專案為
1.SpringCloudServiceCenter 註冊中心
2.SpringCloudConfig 配置中心
3.SpringCloudServiceI 服務I
4.SpringCloudServiceIII 服務III
5.SpringCloudCustomerI ribbon
6.SpringCloudCustomerII feign

服務熔斷

一.在ribbon中使用hystrix

SpringCloudCustomerI 基礎上擴充套件
1.新增依賴

		<!-- 熔斷/降級 -->
		<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
		</dependency>

2.修改MyCustomerController.java。
新增如下內容
新增@HystrixCommand(fallbackMethod = "fallbackInfo")註解,fallbackMethod 為服務不可用時將會呼叫的方法

	@ResponseBody
	@RequestMapping(value="/CgetServiceIData")
	@HystrixCommand(fallbackMethod = "fallbackInfo")
	public String getServiceIData() {
		return getServiceI();
	}
	
	String fallbackInfo() {
		return "The service is down!";
	}

3.啟動項SpringCloundCustomerIApplication.java
添加註解。

//兩個裡選一個即可
@EnableHystrix
@EnableCircuitBreaker

之前看各種部落格時總能看到@EnableHystrix@EnableCircuitBreaker交替出現,那麼它們有什麼區別呢?其實只要點開看一下就知道了。
@EnableHystrix

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {

}

@EnableCircuitBreaker

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {

}

實際上@EnableHystrix其實就是呼叫的@EnableCircuitBreaker。

4.測試
(1)啟動註冊中心,配置中心,服務I,服務III,服務消費者I。
檢視註冊中心http://localhost:8761/
在這裡插入圖片描述
嘗試訪問http://localhost:8770/CApi/CgetServiceIData
在這裡插入圖片描述
在這裡插入圖片描述
因為服務I和III都啟動且沒問題,所以輸出會以上面的情況交替。
(2)然後我們嘗試關閉服務I。
在這裡插入圖片描述
關閉該服務,檢視註冊中心該服務是否關閉了。
在這裡插入圖片描述
然後嘗試訪問http://localhost:8770/CApi/CgetServiceIData
在這裡插入圖片描述
會發現一直都是如上輸出,從這點看,我這裡的ribbon應該預設設定成超時斷連了。如果你那邊沒有設定的話,應該有時會出現The service is down!內容。
(3)然後嘗試下讓服務I的服務超時。
修改SpringCloudServiceI專案的ServiceApiController.java中的getInfo方法
新增一個3秒的執行緒休眠。

@ResponseBody
	@RequestMapping(value="/getInfo")
	public String getInfo() {
        try {
            Thread.sleep(3000);//hystrix熔斷預設超時時間為2秒,這裡模擬超時
        } catch (InterruptedException e) {
            e.printStackTrace();
        }		
		return "serviceI+"+name;
	}

然後啟動服務I,檢視註冊中心
在這裡插入圖片描述

嘗試訪問http://localhost:8770/CApi/CgetServiceIData
在這裡插入圖片描述
在這裡插入圖片描述
能看到服務III還能正常提供資料,但是服務I會因為超時而返回之前寫好的錯誤資訊。

二.在feign中使用hystrix

SpringCloudCustomerII 基礎上擴充套件
1.因為feign中就已經包含了hystrix,所以不需要額外新增依賴,保持原來的即可。
2.如果你使用的Spring Cloud是低版本的話,需要在配置檔案application.properties中新增配置。因為老版本Spring Cloud的話,feign中的hystrix是預設關閉的。

feign.hystrix.enabled=true

3.修改MyCustomerController.java
新增一個服務介面,只獲取服務I和服務III的資訊

	@ResponseBody
	@RequestMapping(value="/getServiceIData")
	public String getServiceIData(@RequestParam String name) {
		String result="";
		
		result+=name+myServiceIService.getInfo();
		
		return result;
	}

4.修改MyServiceIService.java介面
因為集成了hystrix,所以可以直接使用fallback來指定訪問失敗時返回的方法。
並且fallback後填寫的類需要實現被填寫的介面。即MyServiceIErrorService要實現MyServiceIService

@Component
@FeignClient(value="myServiceI",fallback=MyServiceIErrorService.class)
public interface MyServiceIService {
	@ResponseBody
	@RequestMapping(value="/myServiceI/Api/getInfo")
	public String getInfo();
}

5.新增MyServiceIErrorService.java
實現MyServiceIService,這樣在訪問MyServiceIServicegetInfo方法失敗後就會返回MyServiceIErrorServicegetInfo方法

package com.my.customerII.api;

import org.springframework.stereotype.Component;

@Component
public class MyServiceIErrorService implements MyServiceIService{
	public String getInfo() {
		return "The Service is down!";
	}
}

6.啟動測試,什麼?你問啟動項不用加什麼註解嗎?確實不用,都整合在@EnableFeignClients中了_(:з」∠*)_
啟動服務註冊中心,配置中心,服務I,服務III,服務消費者II。
訪問註冊中心http://localhost:8761/
在這裡插入圖片描述
訪問http://localhost:8771/CApi/getServiceIData?name=123
多訪問幾次,可以看到如下兩種輸出,因為服務I中的介面故意新增睡眠3S。而hystrix認定超時時間是2S,所以這裡在負載均衡到服務I時,就會判斷該服務掛掉了,就會返回預設的錯誤資訊。而服務III的介面還是訪問正常。
在這裡插入圖片描述
在這裡插入圖片描述
可以試下關閉服務I,結果應該是如上一樣。

三.hystrix監控

hystrix可以監控添加了hystrix熔斷器介面,並返回訪問成功率,訪問速度等等。
這裡在
1.新增依賴

		<!-- hystrix監控 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
		</dependency>

2.啟動器
新增如下註解SpringCloundCustomerIApplication.java

@EnableHystrixDashboard

然後如果用的是Spring Boot 2.X 版本的話,恭喜,你需要多配置一點東西。
在啟動項里加上這個就行了。

registrationBean.addUrlMappings("/hystrix.stream");會影響到之後訪問監控

/**
	 * spring boot 2.X
	 * @return
	 */
	@Bean
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

3.測試
啟動註冊中心,配置中心,服務I,服務III,服務消費者I。
在這裡插入圖片描述
訪問http://localhost:8770/hystrix
如果之前配置的是registrationBean.addUrlMappings("/hystrix.stream")的話,就在第一個空格中填寫http://localhost:8770/hystrix.stream,title隨便填一個值即可,然後點選montor stream按鈕。
在這裡插入圖片描述
然後可以看到如下介面,如果出現如下介面,那麼表示你用的是Spring Boot 2.X版本了,需要做第2步操作
在這裡插入圖片描述
正常的話是下圖
在這裡插入圖片描述
然後新開一個頁面訪問http://localhost:8770/CApi/CgetServiceIData幾次
再去看剛才的hystrix監控中心,可以看到如下
在這裡插入圖片描述
然後就可以看到服務介面的統計資訊了。

程式碼下載