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監控中心,可以看到如下
然後就可以看到服務接口的統計信息了。