18,熔斷器Hystrix

熔斷器


雪崩效應

在微服務架構中通常會有多個服務層調用,基礎服務的故障可能會導致級聯故障,進而造成整個系統不可用的情況,這種現象被稱爲服務雪崩效應。雪崩效應是一種因“服務提供者”的不可用導致“服務消費者” 的不可用,並將不可用逐漸放大的過程。

如下圖所示:a爲服務提供者,b爲a 的服務消費者,c和d是b 的服務消費者。A不可用引起了b的不可用,並將不可用像滾雪球一樣放大到c和D時,雪崩效應就開始了。


熔斷器

熔斷器的原理很簡單,如同電力過載保護器,他可以實現快速失敗,如果他在一段內偵測到許多類似的錯誤,會強迫其以後的多個調用快速失敗,不在訪問遠程服務器,從而防止應用程序不斷的嘗試執行可能的失敗的操作,從而使得應用程序執行而不用等待修正錯誤,或者浪費cpu時間去等到長時間的超時產生。熔斷器可以使用程序能夠診斷錯誤是否已經修正,,如果已經修正,應用程序會再次嘗試調用操作。

熔斷器模式就像是那些容易導致錯誤的操作的一種代理。這種代理能夠記錄最近調用發生的錯誤次數,然後決定使用允許操作繼續,或者而立即返回錯誤。 熔斷器開關相互轉換的邏輯如下圖;


熔斷器就是保護服務高可用的最後一道防線。

Hystrix特性

1,斷路器機制

斷路器很好理解,當Hystrix Command請求後端服務失敗數量超過一定的比例(默認爲50%)。斷路器會切換到開路狀態(open)。這時候所有的請求會直接失敗而不會發送到後端服務。斷路器保持在開路狀態一段時間後(默認5秒)自動切換到版開路狀態(HALF-OPEN),這時候會判斷下一次請求的返回狀況,如果請求成功,斷路器切回閉路狀態(CLOSED),否則重新切換到開路狀態(OPEN),Hystrix的斷路器就像我們家庭電路中的保險絲,一旦後端服務不可用,斷路器會直接切斷請求鏈接,避免發送大量無效請求影響吞吐量,並且斷路器有我檢測並恢復的能力。

2,fallback

Fallback相當於是降級操作,對於查詢操作,我們可以實現一個fallback方法,當請求後端服務出現異常的時候,可以使用fallback方法返回的值。fallback方法返回的值一般設置默認值或者來自緩存。

資源隔離

在hystrix中,主要通過線程池來實現資源隔離,通常在使用的時候我們會根據調用的遠程服務劃分出等多個線程池,例如調用產品服務的Command放入A線程池,調用賬戶服務COMMAND放入B線程池,這樣做的主要優點是運行環境被隔離開了,這樣就算調用服務的代碼存在存在Bug或者由於其他的原因導致自己所在線程池被耗盡時,不會對系統的其他服務造成影響,但是帶來的代價就是維護多個線程池會對系統帶來額外的性能開銷。如果是對性能有嚴格要求而且確信自己調用服務客戶端代碼不會出現問題的話,可以使用hytrix 信號模式(Semaphores)來隔離資源。

Feign Hystrix


因爲熔斷只是作用在服務調用這端,因次我們需要添加配置
1,配置文件
application.properties添加

spring.application.name=spring-cloud-consumer
server.port=9001
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
feign.hystrix.enabled=true     #熔斷

2,feign的接口類

package com.taotao.consumer.sevice;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name="spring-cloud-producer")
public interface HelloRemote {
    @RequestMapping("/hello")
    public String hello(@RequestParam(value = "name") String name);
    @RequestMapping("/getName")
    public String getName(@RequestParam("name") String name);  //必須加上@RequestParam("name") 才能傳值
}



3,controller類

package com.taotao.consumer.controller;

import com.taotao.consumer.sevice.HelloRemote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    HelloRemote helloRemote;
    @RequestMapping("/index")
    public String index(String name){
        return  helloRemote.hello(name);
    }

    @RequestMapping("/getOrderName")
    public  String getOrderName(String name){
        return  helloRemote.getName(name);
    }
}

4,創建回調類
創建HelloRemoteHystrix類繼承與HelloRemote實現回調的方法

@Component
public class HelloRemoteHystrix implements HelloRemote{

    @Override
    public String hello(@RequestParam(value = "name") String name) {
        return "hello" +name+", this messge send failed ";
    }
}

5,添加fallback屬性
在HelloRemote類添加指定fallback類,在服務熔斷的時候返回fallback類中的內容。

@FeignClient(name= "spring-cloud-producer",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {

    @RequestMapping(value = "/hello")
    public String hello(@RequestParam(value = "name") String name);

}

4、測試
那我們就來測試一下看看效果吧。

依次啓動spring-cloud-eureka、spring-cloud-producer、spring-cloud-consumer三個項目。

瀏覽器中輸入:http://localhost:9001/hello/neo

返回:hello neo,this is first messge

說明加入熔斷相關信息後,不影響正常的訪問。接下來我們手動停止spring-cloud-producer項目再次測試:

瀏覽器中輸入:http://localhost:9001/hello/neo

返回:hello neo, this messge send failed

根據返回結果說明熔斷成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章