SpringCloud--Hystrix熔斷器 (六)

一柱锹、Hystrix簡(jiǎn)介

??在分布式環(huán)境中拜鹤,許多服務(wù)依賴項(xiàng)中的一些必然會(huì)失敗。Hystrix是一個(gè)庫(kù)钧舌,通過(guò)添加延遲容忍和容錯(cuò)邏輯担汤,幫助你控制這些分布式服務(wù)之間的交互。Hystrix通過(guò)隔離服務(wù)之間的訪問(wèn)點(diǎn)洼冻、停止級(jí)聯(lián)失敗和提供回退選項(xiàng)來(lái)實(shí)現(xiàn)這一點(diǎn)崭歧,所有這些都可以提高系統(tǒng)的整體彈性。
Hystrix如何解決依賴隔離:


Hystrix如何解決依賴隔離

1撞牢、包裹請(qǐng)求:使用HystrixCommand包裹對(duì)依賴的調(diào)用邏輯率碾,每個(gè)命令在獨(dú)立的線程中執(zhí)行,使用了設(shè)計(jì)模式中的“命令模式”屋彪;
2所宰、跳閘機(jī)制:當(dāng)某服務(wù)的錯(cuò)誤率超過(guò)一定閾值時(shí),Hystrix可以自動(dòng)或者手動(dòng)跳閘撼班,停止請(qǐng)求該服務(wù)一段時(shí)間歧匈;
3、資源隔離:Hystrix為每個(gè)依賴都維護(hù)了一個(gè)小型的線程池(或者信號(hào)量)砰嘁。如果該線程已滿件炉,則發(fā)向該依賴的請(qǐng)求就會(huì)被立即拒絕,而不是排隊(duì)等候矮湘,從而加速失敗判定斟冕;
4、監(jiān)控:Hystrix可以近乎實(shí)時(shí)地監(jiān)控運(yùn)行指標(biāo)和配置的變化缅阳,例如成功磕蛇、失敗、超時(shí)十办、以及被拒絕的請(qǐng)求等秀撇;
5、回退機(jī)制:當(dāng)請(qǐng)求失敗向族、超時(shí)呵燕、被拒絕,或當(dāng)斷路器打開時(shí)件相,執(zhí)行回退邏輯再扭,回退邏輯由開發(fā)人員自行提供氧苍,如返回一個(gè)缺省值;
6泛范、自我修復(fù):斷路器打開一段時(shí)間后让虐,會(huì)自動(dòng)進(jìn)入“半開”狀態(tài),此時(shí)斷路器可允許一個(gè)請(qǐng)求訪問(wèn)依賴的服務(wù)罢荡,若請(qǐng)求成功赡突,則斷路器關(guān)閉,否則斷路器轉(zhuǎn)為“打開”狀態(tài)柠傍;

形成過(guò)程:

1)服務(wù)提供者不可用

a)硬件故障:硬件損壞造成的服務(wù)器主機(jī)宕機(jī), 網(wǎng)絡(luò)硬件故障造成的服務(wù)提供者的不可訪問(wèn)
b)程序Bug:
c) 緩存擊穿:緩存擊穿一般發(fā)生在緩存應(yīng)用重啟, 所有緩存被清空時(shí),以及短時(shí)間內(nèi)大量緩存失效時(shí). 大量的緩存不命中, 使請(qǐng)求直擊后端,造成服務(wù)提供者超負(fù)荷運(yùn)行,引起服務(wù)不可用
d)用戶大量請(qǐng)求:在秒殺和大促開始前,如果準(zhǔn)備不充分,用戶發(fā)起大量請(qǐng)求也會(huì)造成服務(wù)提供者的不可用

2)重試加大流量

a)用戶重試:在服務(wù)提供者不可用后, 用戶由于忍受不了界面上長(zhǎng)時(shí)間的等待,而不斷刷新頁(yè)面甚至提交表單
b)代碼邏輯重試: 服務(wù)調(diào)用端的會(huì)存在大量服務(wù)異常后的重試邏輯

3)服務(wù)調(diào)用者不可用

a)同步等待造成的資源耗盡:當(dāng)服務(wù)調(diào)用者使用同步調(diào)用 時(shí), 會(huì)產(chǎn)生大量的等待線程占用系統(tǒng)資源. 一旦線程資源被耗盡,服務(wù)調(diào)用者提供的服務(wù)也將處于不可用狀態(tài), 于是服務(wù)雪崩效應(yīng)產(chǎn)生了麸俘。

??為了保證其高可用,單個(gè)服務(wù)通常會(huì)集群部署惧笛。由于網(wǎng)絡(luò)原因或者自身的原因从媚,服務(wù)并不能保證100%可用,如果單個(gè)服務(wù)出現(xiàn)問(wèn)題患整,調(diào)用這個(gè)服務(wù)就會(huì)出現(xiàn)線程阻塞拜效,此時(shí)若有大量的請(qǐng)求涌入,Servlet容器的線程資源會(huì)被消耗完畢各谚,導(dǎo)致服務(wù)癱瘓紧憾。服務(wù)與服務(wù)之間的依賴性,故障會(huì)傳播昌渤,會(huì)對(duì)整個(gè)微服務(wù)系統(tǒng)造成災(zāi)難性的嚴(yán)重后果赴穗,這就是服務(wù)故障的“雪崩”效應(yīng)。
Hystrix是一個(gè)用于分布式系統(tǒng)的延遲和容錯(cuò)的開源庫(kù)膀息。在分布式系統(tǒng)里般眉,許多依賴不可避免的調(diào)用失敗,比如超時(shí)潜支、異常等甸赃,Hystrix能夠保證在一個(gè)依賴出問(wèn)題的情況下,不會(huì)導(dǎo)致整個(gè)服務(wù)失敗冗酿,避免級(jí)聯(lián)故障埠对,以提高分布式系統(tǒng)的彈性。


Hystrix
  1. 服務(wù)雪崩
    ??多個(gè)微服務(wù)之間調(diào)用的時(shí)候裁替,假設(shè)微服務(wù)A調(diào)用微服務(wù)B和微服務(wù)C项玛,微服務(wù)B和微服務(wù)C有調(diào)用其他的微服務(wù),這就是所謂的”扇出”弱判,如扇出的鏈路上某個(gè)微服務(wù)的調(diào)用響應(yīng)式過(guò)長(zhǎng)或者不可用襟沮,對(duì)微服務(wù)A的調(diào)用就會(huì)占用越來(lái)越多的系統(tǒng)資源,進(jìn)而引起系統(tǒng)雪崩,所謂的”雪崩效應(yīng)”臣嚣。

  2. 斷路器:
    ??“斷路器”本身是一種開關(guān)裝置,當(dāng)某個(gè)服務(wù)單元發(fā)生故障監(jiān)控(類似熔斷保險(xiǎn)絲)剥哑,向調(diào)用方法返回一個(gè)符合預(yù)期的硅则、可處理的備選響應(yīng)(FallBack),而不是長(zhǎng)時(shí)間的等待或者拋出調(diào)用方法無(wú)法處理的異常株婴,這樣就保證了服務(wù)調(diào)用方的線程不會(huì)被長(zhǎng)時(shí)間怎虫、不必要地占用,從而避免了故障在分布式系統(tǒng)中的蔓延困介。乃至雪崩大审。

  3. 服務(wù)熔斷:
    ??熔斷機(jī)制是應(yīng)對(duì)雪崩效應(yīng)的一種微服務(wù)鏈路保護(hù)機(jī)制,
    ??當(dāng)扇出鏈路的某個(gè)微服務(wù)不可用或者響應(yīng)時(shí)間太長(zhǎng)時(shí)座哩,會(huì)進(jìn)行服務(wù)的降級(jí)徒扶,進(jìn)而熔斷該節(jié)點(diǎn)微服務(wù)的調(diào)用,快速返回”錯(cuò)誤”的響應(yīng)信息根穷。當(dāng)檢測(cè)到該節(jié)點(diǎn)微服務(wù)響應(yīng)正常后恢復(fù)調(diào)用鏈路姜骡,在SpringCloud框架機(jī)制通過(guò)Hystrix實(shí)現(xiàn),Hystrix會(huì)監(jiān)控微服務(wù)見調(diào)用的狀況屿良,當(dāng)失敗的調(diào)用到一個(gè)閾值圈澈,缺省是5秒內(nèi)20次調(diào)用失敗就會(huì)啟動(dòng)熔斷機(jī)制,熔斷機(jī)制的注解是@HystrixCommand

二尘惧、Maven依賴

<!-- Hystrix -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

三康栈、 主啟動(dòng)類添加注解EnableCircuitBreaker

@SpringBootApplication
@EnableCircuitBreaker //對(duì)Hystrix熔斷機(jī)制的支持
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

四、熔斷測(cè)試

@RequestMapping(value = "/user/get/{id}", method = RequestMethod.GET)
// 如果當(dāng)前調(diào)用的get()方法出現(xiàn)了錯(cuò)誤喷橙,則執(zhí)行fallback
@HystrixCommand(fallbackMethod="getFallback")
public Object get(@PathVariable("id") long id) {
    String vo=null;    // 接收數(shù)據(jù)庫(kù)的查詢結(jié)果
    if (vo == null) {    // 數(shù)據(jù)不存在啥么,假設(shè)讓它拋出個(gè)錯(cuò)誤
        throw new RuntimeException("部門信息不存在!") ;
    }
    return vo ;
}

/**
 * 此時(shí)方法的參數(shù) 與get()一致
 * @param id
 * @return
 */
public Object getFallback(@PathVariable("id") long id) {
    User vo = new User() ;
    vo.setId(1);
    vo.setUsername("【ERROR】User-Service-Hystrix");    // 錯(cuò)誤的提示
    return vo ;
}

現(xiàn)在的處理情況是:服務(wù)器出現(xiàn)了錯(cuò)誤(但并不表示提供方關(guān)閉)重慢,那么此時(shí)會(huì)調(diào)用指定方法的 fallback 處理饥臂。
什么情況下會(huì)觸發(fā)fallback方法?

名字 描述 觸發(fā)fallback
EMIT 值傳遞NO
SUCCESS 執(zhí)行完成似踱,沒(méi)有錯(cuò)誤 NO
FAILURE 執(zhí)行拋出異常 YES
TIMEOUT 執(zhí)行開始隅熙,但沒(méi)有在允許的時(shí)間內(nèi)完成 YES
BAD_REQUEST 執(zhí)行拋出HystrixBadRequestException NO
SHORT_CIRCUITED 斷路器打開核芽,不嘗試執(zhí)行 YES
THREAD_POOL_REJECTED 線程池拒絕囚戚,不嘗試執(zhí)行 YES
SEMAPHORE_REJECTED 信號(hào)量拒絕轧简,不嘗試執(zhí)行 YES

fallback方法在什么情況下會(huì)拋出異常

名字 描述 拋異常
FALLBACK_EMIT Fallback值傳遞 NO
FALLBACK_SUCCESS Fallback執(zhí)行完成驰坊,沒(méi)有錯(cuò)誤 NO
FALLBACK_FAILURE Fallback執(zhí)行拋出出錯(cuò) YES
FALLBACK_REJECTED Fallback信號(hào)量拒絕,不嘗試執(zhí)行 YES
FALLBACK_MISSING 沒(méi)有Fallback實(shí)例 YES

五、基于Feign使用Hystrix

通常情況下的Hystrix是通過(guò)注解@HystrixCommand的fallbackMethod屬性實(shí)現(xiàn)回調(diào)的,而在Feign中染服,由于Feign是用接口實(shí)現(xiàn)的聲明式Rest,所以Hystrix的通用方法在這里就不適用于Feign了益愈,實(shí)際上在Feign與SpringCloud的依賴庫(kù)中已經(jīng)默認(rèn)的將Hystrix加入其中了靠汁,如圖:


基于Feign使用Hystrix
  1. Maven依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
  1. application.properties配置
server.port=8762
spring.application.name=user-service
#默認(rèn)feign的hystrix為關(guān)閉狀態(tài)
feign.hystrix.enabled=true
# 服務(wù)注冊(cè)
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
  1. 啟動(dòng)類
    啟動(dòng)類添加@EnableFeignClients,控制層通過(guò)注入feign的接口去完成聲明式調(diào)用:
@SpringBootApplication
@EnableFeignClients
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

  1. 接口類
// 接口類上加入的注解中添加屬性fallback,指定回調(diào)類
@FeignClient(name = "USER-SERVICE",fallback = FeignClientFallback.class)
public interface UserFeign {
    @RequestMapping("/getUser")
    public String getUser();

}
  1. 回調(diào)類
/**
 * @Description: 回調(diào)實(shí)現(xiàn)類
 */ 
@Component
class FeignClientFallback implements UserFeign {

    @Override
    public String getUser() {
        System.out.println("熔斷,默認(rèn)回調(diào)函數(shù)");
        return "{\"username\":\"admin\",\"age\":\"-1\"}";
    }
}

6继薛、測(cè)試

   @Autowired
    private UserFeign userFeign;
    @Test
    public void getUser() {
        String str = userFeign .getUser();
        log.info("{}", str);
    }

測(cè)試方法修壕,服務(wù)方法中,產(chǎn)生異常將會(huì)調(diào)用熔斷方法遏考。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末慈鸠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子灌具,更是在濱河造成了極大的恐慌青团,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咖楣,死亡現(xiàn)場(chǎng)離奇詭異督笆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)诱贿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門娃肿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人珠十,你說(shuō)我怎么就攤上這事料扰。” “怎么了焙蹭?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵晒杈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我孔厉,道長(zhǎng)拯钻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任撰豺,我火速辦了婚禮说庭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘郑趁。我一直安慰自己刊驴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捆憎,像睡著了一般舅柜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躲惰,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天致份,我揣著相機(jī)與錄音,去河邊找鬼础拨。 笑死氮块,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诡宗。 我是一名探鬼主播滔蝉,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼塔沃!你這毒婦竟也來(lái)了蝠引?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛀柴,失蹤者是張志新(化名)和其女友劉穎螃概,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸽疾,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吊洼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了制肮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片融蹂。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弄企,靈堂內(nèi)的尸體忽然破棺而出超燃,到底是詐尸還是另有隱情,我是刑警寧澤拘领,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布意乓,位于F島的核電站,受9級(jí)特大地震影響约素,放射性物質(zhì)發(fā)生泄漏届良。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一圣猎、第九天 我趴在偏房一處隱蔽的房頂上張望士葫。 院中可真熱鬧,春花似錦送悔、人聲如沸慢显。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荚藻。三九已至屋灌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間应狱,已是汗流浹背共郭。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疾呻,地道東北人除嘹。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像岸蜗,于是被迫代替她去往敵國(guó)和親尉咕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容