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
,這樣在訪問MyServiceIService
的getInfo
方法失敗後就會返回MyServiceIErrorService
的getInfo
方法
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監控中心,可以看到如下
然後就可以看到服務介面的統計資訊了。