微服務SpringCloud之熔斷器

   學習SpringCloud微服務是參考純潔的微笑博客,看到他提到股市的熔斷我也忍不住吐槽一下,記得當時實施熔斷第一天就熔斷了,現在想想也還是搞笑,從之前的全民炒股到現在的全民炒房,都是一個炒字,問題是現在的房市和之前股市的5000點一樣,再加上貿易戰、人口老齡化等因素,不知道能撐多久,可能是一悲觀主義者,我是不太樂觀。

   熔斷和家裏的保險絲一樣,啓動保護作用,電壓過高或過低會導致電器損壞,保險絲的作用就是當電壓異常時直接斷掉,不至於影響其他電器的使用,而且保險絲也只是一根線,壞掉也影響不大,是預防雪崩的一種方法。Redis裏面有雪崩和穿透,SpringCloud中也有雪崩。A服務調用B服務、B服務調用C服務,C服務調用D服務,如果D服務掛了,那如果不做保護,C服務也會掛斷,C掛了B也會掛,B掛了A也掛,這樣就會都掛了,這就需要有一個壯士斷腕的勇氣,和習大大的理論是異曲同工之妙。一旦雪崩那恢復的順序正好相反,應該先恢復D服務,再依次恢復C、B、A。不然假如先恢復A,那B還是掛了的,到時候A還是會掛。下面是比較書面的介紹。

1.斷路器機制

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

2.Fallback

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

3.資源隔離

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

在SpringCloud中實現也比較簡單,Feign中已經依賴了Hystrix所以在maven配置上不用做任何改動,只需要三步即可。

1.配置文件

在上一博客的EurekaConsumer基礎上,在屬性文件中啓動fegin的Hystrix功能。

feign.hystrix.enabled=true

2.創建回調類

package com.example.demo;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;

@Component
public class HelloRemoteHystrix implements HelloRemote {
    @Override
    public String hello(@RequestParam(value = "name") String name) {
        return "hello " +name+", this messge send by Hystrix ";
    }
}

3.添加fallback屬性

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

package com.example.demo;

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",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {

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

}

此時已完成引入熔斷器,我們可以測試下。依次啓動服務EurekaServer、生產者EurekaClient、消費者EurekaConsumer。

此時輸入http://localhost:9001/hello?name=cuiyw時,輸出正常如下:

當EurekaClient停止時,再次輸入http://localhost:9001/hello?name=cuiyw,輸出如下,返回的是上面加的熔斷fallback類,說明熔斷成功。

 參考:http://www.ityouknow.com/springcloud/2017/05/16/springcloud-hystrix.html

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