前言:微服務架構應用的特色就是多服務,而服務層之間經過網絡進行通訊,從而支撐起整個應用系統,因此,各個微服務之間不可避免的存在耦合依賴關係。但任何的服務應用實例都不可能永遠的健康或網絡不可能永遠的都相安無事,因此一旦某個服務或局部業務發生了故障,會致使系統的不可用,咱們知道當故障累積到必定程度就會形成系統層面的災害,也就是級聯故障,也叫雪崩效應,因此微服務須要在故障累計到上限以前阻止或疏通這些故障以保證系統的穩固安全,在市面上已經有不少這樣的框架來解決這樣的問題,如Twitter的Finagle、Netflix的Hystrix和Google的Stubby等,下面就簡單介紹下Hystrix和Hystrix在SpringCloud中的應用。html
Hystrix(https://github.com/Netflix/Hystrix)是由Netflix開源的一個延遲和容錯庫,用於隔離訪問遠程系統、服務或者第三方庫,防止級聯失敗,從而提高系統的可用性、容錯性與局部應用的彈性,是一個實現了超市機制和斷路器模式的工具類庫。java
一、包裹請求:使用HystrixCommand包裹對依賴的調用邏輯,每一個命令在獨立的線程中執行,使用了設計模式中的「命令模式」;
二、跳閘機制:當某服務的錯誤率超過必定閾值時,Hystrix能夠自動或者手動跳閘,中止請求該服務一段時間;
三、資源隔離:Hystrix爲每一個依賴都維護了一個小型的線程池(或者信號量)。若是該線程已滿,則發向該依賴的請求就會被當即拒絕,而不是排隊等候,從而加速失敗斷定;
四、監控:Hystrix能夠近乎實時地監控運行指標和配置的變化,例如成功、失敗、超時、以及被拒絕的請求等;
五、回退機制:當請求失敗、超時、被拒絕,或當斷路器打開時,執行回退邏輯,回退邏輯由開發人員自行提供,如返回一個缺省值;
六、自我修復:斷路器打開一段時間後,會自動進入「半開」狀態,此時斷路器可容許一個請求訪問依賴的服務,若請求成功,則斷路器關閉,不然斷路器轉爲「打開」狀態;git
①、建立基於Eureka和Ribbon的服務端 eureka-ribbon-server和兩個客戶端生產者 eureka-ribbon-client2、消費者:複製項目eureka-ribbon-client,將AritfactId修改成eureka-hystrix-client;github
②、在消費者中添加依賴:web
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
③、在啓動類ClientApplication上添加@EnableHystrix或@EnableCircuitBreaker;spring
④、修改HystrixController,在其中添加getUser方法,並添加熔斷回調方法註解及回調方法:設計模式
@HystrixCommand(fallbackMethod = "getDefaultUser")
@RequestMapping("/getUser")
public String getUser() {
return restTemplate.getForObject("http://client-87/getUser", String.class);
}
private String getDefaultUser() {
System.out.println("熔斷,默認回調函數");
return "{\"username\":\"admin\",\"age\":\"-1\"}";
}
⑤、分別啓動eureka-ribbon-server、eureka-ribbon-client二、eureka-hystrix-client,調用localhost:8765/getUser,如圖:安全
⑥、關掉eureka-ribbon-client2後,再次調用,發現熔斷器調用了回調函數,如圖:網絡
關於Hystrix的配置屬性,能夠自行測試瞭解:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration架構
而咱們如何知道hystrix是否開啓,能夠經過SpringBoot Actuator組件查看,注意:出發回調並非hystrix打開,他的狀態還處在關閉,若失敗率達到閾值(默認爲5秒內20次失敗)後纔會打開;
一般狀況下的Hystrix是經過註解@HystrixCommand的fallbackMethod屬性實現回調的,而在Feign中,因爲Feign是用藉口實現的聲明式Rest,因此Hystrix的通用方法在這裏就不適用於Feign了,實際上在Feign與SpringCloud的依賴庫中已經默認的將Hystrix加入其中了,如圖:
那麼,該怎麼實現呢?
pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
application.properties屬性配置文件:
server.port=8762
spring.application.name=client-8762
#默認feign的hystrix爲關閉狀態
feign.hystrix.enabled=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
啓動類添加@EnableFeignClients,控制層經過注入feign的接口去完成聲明式調用:
feign的接口:
package com.cn.feign; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; //接口類上加入的註解中添加屬性fallback,指定回調類 @FeignClient(name = "CLIENT-87",fallback = FeignClientFallback.class) public interface UserFeign { @RequestMapping("/getUser") public String getUser(); }
建立回調類:
package com.cn.feign; import org.springframework.stereotype.Component; /** * @Description: 回調實現類 * @Param: * @return: * @Author: * @Date: 2018/6/19 */ @Component class FeignClientFallback implements UserFeign { @Override public String getUser() { System.out.println("熔斷,默認回調函數"); return "{\"username\":\"admin\",\"age\":\"-1\"}"; } }
2.測試結果以下:
在未關閉生產者服務實例時:
關閉實例後:
代碼示例:https://gitee.com/lfalex/springcloud-example( eureka-hystrix-client、 eureka-feign-hystrix-client、 eureka-ribbon-client2、 eureka-ribbon-server)
參考書籍:《SpringCloud與Docker微服務架構實戰》周力著