什麼是Hystrix
Hystrix 在SpringCloud中負責服務熔斷服務降級的作用。
Hystrix 存在的目的也是為了防止過多逾時導緻系統癱瘓。比如多個服務之間的互相調用,如下圖:
訂單->商品->積分->日志
訂單->支付->日志
商品->風控->日志
服務之間互相調用,假設某個鍊路上的某個服務比如日志服務逾時了,不可被調用,那麼其他的服務全部卡死,導緻崩潰。
舉一個生活中的例子:
在家裡,我開了很多電器,這個時候如果沒有一個保護裝置的話,由于某個電器過載,最終會導緻整個電路斷掉,那麼每戶人家肯定會有一個裝置叫做
保險絲
,那麼Hystrix斷路器就起到了保險絲的作用,他可以保護整個系統。
Hystrix在分布式系統或者微服務中,一旦出現了逾時或者依賴服務不可用調用失敗異常等情況,他能夠保證整個系統不會整體當機崩潰,進而提高整個系統的健壯性。
Hystrix的原理就是當某一個服務發生故障的時候,這個時候是不會有任何的正常響應的,但是通過Hystrix可以傳回一個備用響應,也就是所謂的backup,如此一來,發生異常的系統就不會造成不必要的逾時等異常現象,這就好比打籃球,上場必須要5人,但是如果有人受傷要下場,這個時候就必須要有backup球員,如果沒有,這個球隊很難進行比賽了。
簡單一句話總結,就是Hystrix可以保證在衆多微服務中一個服務出現了問題不會引發整體系統奔潰的一個開源元件。
服務熔斷
熔斷是一種微服務鍊路的保護機制,當某個服務(依賴)不可用/當機/逾時/異常的時候,會進行服務的熔斷(是一個開關,會開啟),這個發生故障的節點就被
熔斷了
也就是不可用,不會再讓使用者調用到,那麼此時就需要降級,來直接會傳回一個錯誤的異常響應資訊。當這個節點OK恢複了,hystrix會檢測到,然後再把他恢複到整個鍊路。
熔斷機制在很多行業裡都有,比如股市,金融行業,都是為了更好更有效的控制,把損失控制在一定的範圍内。
代碼示範
- pom 中加入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 啟動類開啟熔斷器
@EnableCircuitBreaker
- 編寫錯誤的controller
// 一旦服務調用失敗,發生異常,會調用@HystrixCommand中的[graceDisplay]方法,這個方法就是兜底方法
@HystrixCommand(fallbackMethod = "graceDisplay")
public String helloHystrix() {
Object o = "Hello hystrix~";
int a = 1 / 0;
return "Hello hystrix~";
}
public String graceDisplay() {
return "Hello another me~";
}
- 測試:
- 如果正常通路,顯示
Hello hystrix~
- 發生異常熔斷,則展示:
- 如果正常通路,顯示
伺服器降級
當某個服務資源不夠的時候,可以啟用降級處理。
舉一個例子,如下圖:
假設我們家裡用很多電器,其他電器正在使用中并且占用的電流啊電壓啥的很大,空調我這個時候可以不用,把資源給到其他的電器,這時我們是直接把空調插頭拔出,差別于熔斷,熔斷的話是發生異常後和諧的響應資訊,而降級是我把這個服務關停了,随後在響應給使用者。需要注意,由于服務關閉了,是以響應是發生在調用方的,也就是用戶端,比如圖中的
電熱水壺
和
微波爐
。當電壓電流恢複後,我們再把空調插頭插上即可,那麼這就是降級的一種方式。
那麼熔斷和降級的異同點是啥呢?
- 相同點:
- 都是為了提升系統的可靠性
- 都為了正确的傳回響應給使用者
- 不同點:
- 熔斷:被調用的服務方(下遊)發生故障導緻
- 降級:全局整體服務負載過高,有效調動資源服務,由調用方(上遊)控制
熔斷解耦分離
當使用
@HystrixCommand
的時候,每有一個controller的接口api,就會有一個熔斷方法,這是成倍的增長的,數量會很多,維護不友善,是以需要解耦開來。而且,當我們關閉不用的微服務時,上遊還是會調用下遊,是以我們需要在上遊服務這塊,去增加降級的方法,如果服務無法調用,則調用上遊服務中的降級方法即可。并且下遊服務如果被我們關閉,上遊的調用還是可以有響應給使用者的。
@Component
public class HystrixFactoryCallback implements FallbackFactory<HystrixFactoryControllerApi> {
@Override
public HystrixFactoryControllerApi create(Throwable throwable) {
return new HystrixFactoryControllerApi() {
@Override
public String helloFactory() {
return "優雅的處理,隻在用戶端直接傳回,下遊服務關閉不影響";
}
};
}
}
@FeignClient(value = EurekaServiceList.SERVICE_HYSTRIX, fallbackFactory = HystrixFactoryCallback.class)
public interface HystrixFactoryControllerApi {
// 目前類的所有接口隻要有問題都會被HystrixFactoryCallback給處理
// 測試hystrix降級解耦
@GetMapping("/helloFactory")
public String helloFactory();
}
spring:
main:
allow-bean-definition-overriding: true # 允許 @FeignClient 同名
feign:
hystrix:
enabled: true # 開啟@FeignClient的降級功能 fallbackFactory
上遊:
@Autowired
HystrixFactoryControllerApi hystrixFactoryControllerApi;
@GetMapping("/testHystrixFactoryApi")
public Object testHystrixFactoryApi() {
String result = hystrixFactoryControllerApi.helloFactory();
return result;
}
下遊:
@RestController
public class FactoryController implements HystrixFactoryControllerApi {
@Override
public String helloFactory() {
Object o = "Hello hystrix factory~";
int a = 1 / 0;
return "Hello hystrix factory~";
}
}
簡單總結一下
熔斷:當一個服務發生故障異常,這個時候熔斷目前整個服務,把這個服務變的不可被通路,而不是用戶端請求這個服務的時候一直處于逾時。
降級:當服務熔斷後,我們需要提供新的一個兜底接口傳回響應資料,如此一來,用戶端能夠友好的接受到響應消息。
官網itzixi.com
微信公衆号:BeJavaGod
新浪微網誌
知乎
簡書
cnblogs
今日頭條
豆瓣
--> 同步更新
