Hystrix從入門到精通

Hystrix Logo

1.Hystrix是什么?

hystrix對應(yīng)的中文名字是“豪豬”残炮,豪豬周身長滿了刺半等,能保護自己不受天敵的傷害,代表了一種防御機制拾氓,這與hystrix本身的功能不謀而合冯挎,因此Netflix團隊將該框架命名為Hystrix,并使用了對應(yīng)的卡通形象做作為logo咙鞍。

在一個分布式系統(tǒng)里房官,許多依賴不可避免的會調(diào)用失敗,比如超時续滋、異常等翰守,如何能夠保證在一個依賴出問題的情況下,不會導(dǎo)致整體服務(wù)失敗疲酌,這個就是Hystrix需要做的事情蜡峰。Hystrix提供了熔斷了袁、隔離、Fallback湿颅、cache载绿、監(jiān)控等功能,能夠在一個油航、或多個依賴同時出現(xiàn)問題時保證系統(tǒng)依然可用崭庸。

2.用一個例子快速進入Hystrix

Hystrix的核心功能,就是在調(diào)用遠程服務(wù)時的熔斷機制劝堪。下面用一個簡單的例子來說明Hystrix的核心功能冀自。

1.例子基于spring-boot,所以首先新建一個空的spring-boot項目秒啦。建項目的過程此處略過熬粗。

2.添加maven依賴:

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.9</version>
</dependency>

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-metrics-event-stream</artifactId>
    <version>1.5.9</version>
</dependency>

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.9</version>
</dependency>

3.新建configuration類

package com.mogujie.marketing.hystrixTest.configuration;

import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HystrixConfiguration {
    @Bean
    public HystrixCommandAspect hystrixAspect() {
        return new HystrixCommandAspect();
    }

    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registration.addUrlMappings("/hystrix.stream");
        return registration;
    }
}

4.新建RemoteService,代表依賴的遠程服務(wù)余境。

package com.mogujie.marketing.hystrixTest.service;

import org.springframework.stereotype.Service;

@Service("remoteService")
public class RemoteService {

    public Object getUser() {
        Thread.sleep(2500);
        return "user";
    }
}

5.新建UserController驻呐,調(diào)用遠程服務(wù)。

package com.mogujie.marketing.hystrixTest.controller;

import com.mogujie.marketing.hystrixTest.service.RemoteService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping({"/test"})
public class UserController {

    @Autowired
    private RemoteService remoteService;

    @RequestMapping(value = "/user")
    @HystrixCommand(fallbackMethod = "fallback", threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "100"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "20")}, commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "1")

    })
    public Object getUser() throws InterruptedException {
        Object user = remoteService.getUser();
        return user;
    }

    public Object fallback(Throwable e) {
        e.printStackTrace();
        return "test";
    }
}

6.瀏覽器調(diào)用http://127.0.0.1/test/user可以看到正常返回的結(jié)果芳来。調(diào)整Thread.sleep的時間為3000含末,可以看到fallback函數(shù)返回的結(jié)果。

從上面的例子可以快速體會到Hystrix給遠程服務(wù)調(diào)用帶來的好處即舌,只需要簡單的配置一個注解佣盒,就能給遠程服務(wù)加上超時時間&錯誤回調(diào)。

Hystrix可以支持RPC顽聂、DB肥惭、HTTP等遠程服務(wù)的超時&錯誤回調(diào),甚至可以做本地服務(wù)的超時&錯誤回調(diào)紊搪。剛剛的例子就是模擬本地服務(wù)執(zhí)行超時的情況蜜葱。

一般來說,RPC框架都有基本的超時機制耀石,但是錯誤處理和功能降級往往要自己來實現(xiàn)牵囤,Hystrix幫我省略了這部分冗余的代碼,只需要寫一個回調(diào)函數(shù)滞伟,簡單配置一下就完工了揭鳞。

3.Hystrix的配置項

那Hystrix有哪些配置項?那些配置項又支持哪些功能诗良?這些功能又在什么情況下被用到呢汹桦?解決這些問題是Hystrix進階的關(guān)鍵。

3.1 Hystrix有哪些配置項?

官方配置項地址:配置項詳解.

Execution 執(zhí)行

  • execution.isolation.strategy:設(shè)置方法執(zhí)行的隔離策略鉴裹∥杪妫可選線程池或者信號量钥弯。具體分析參考這篇文章Hystrix系列-5-Hystrix的資源隔離策略
  • execution.isolation.thread.timeoutInMilliseconds:設(shè)置調(diào)用者等待命令執(zhí)行的超時限制督禽,超過此時間脆霎,HystrixCommand被標記為TIMEOUT,并執(zhí)行回退邏輯狈惫。
  • execution.timeout.enabled:執(zhí)行是否有超時限制睛蛛。
  • execution.isolation.thread.interruptOnTimeout:當超時的時候是否中斷
  • execution.isolation.thread.interruptOnCancel:當發(fā)生cancel事件后是否中斷
  • execution.isolation.semaphore.maxConcurrentRequests:當使用信號量隔離的時候,此配置有效胧谈。官方給出5000請求只需要2個忆肾。

Fallback 降級

  • fallback.isolation.semaphore.maxConcurrentRequests:最大并發(fā)數(shù),超過此并發(fā)則拒絕請求菱肖。
  • fallback.enabled:是否打開降級

Circuit Breaker 熔斷器

  • circuitBreaker.enabled:是否打開熔斷器客冈。
  • circuitBreaker.requestVolumeThreshold:時間窗口內(nèi)最小請求數(shù),當小于這個請求數(shù)稳强,即使全部失敗也不會熔斷场仲。
  • circuitBreaker.sleepWindowInMilliseconds:熔斷后,請求retry的時間間隔
  • circuitBreaker.errorThresholdPercentage:失敗率閾值退疫,超過這個失敗率就會熔斷
  • circuitBreaker.forceOpen:是否強制開啟熔斷渠缕,這樣會導(dǎo)致拒絕所有請求
  • circuitBreaker.forceClosed:是否強制關(guān)閉熔斷,這樣任何原因都無法觸發(fā)熔斷褒繁。注:優(yōu)先級小于強制開啟亦鳞。

Metrics 度量

  • metrics.rollingStats.timeInMilliseconds:設(shè)置統(tǒng)計滾動窗口的長度,以毫秒為單位棒坏。用于監(jiān)控和熔斷器蚜迅。
    滾動窗口被分隔成桶(bucket)。并進行滾動俊抵。 例如這個屬性設(shè)置10000ms,一個桶就是1s坐梯。
  • metrics.rollingStats.numBuckets :統(tǒng)計窗口的桶數(shù)量徽诲。
  • metrics.rollingPercentile.enabled:執(zhí)行時間是否被跟蹤,并且計算各個百分比吵血,50%,90%等的時間谎替。
  • metrics.rollingPercentile.timeInMilliseconds:設(shè)置執(zhí)行時間在滾動窗口中保留時間,用來計算百分比蹋辅。
  • metrics.rollingPercentile.numBuckets:設(shè)置rollingPercentile窗口的桶數(shù)量钱贯。
  • metrics.rollingPercentile.bucketSize :設(shè)置每個桶保存的執(zhí)行時間的最大值。
  • metrics.healthSnapshot.intervalInMilliseconds:采樣時間間隔侦另。

Request Context 請求上下文

  • requestCache.enabled:設(shè)置是否緩存請求秩命,request-scope內(nèi)緩存尉共。hystrix支持將一個請求結(jié)果緩存起來,下一個具有相同key的請求將直接從緩存中取出結(jié)果弃锐,減少請求開銷袄友。要使用該功能必須管理HystrixRequestContext,如果請求B要用到請求A的結(jié)果緩存霹菊,A和B必須同處一個context剧蚣。
  • requestLog.enabled:設(shè)置HystrixCommand執(zhí)行和事件是否打印到HystrixRequestLog中 。

Collapser Properties 壓縮器屬性

  • maxRequestsInBatch:請求合并的最大請求數(shù)
  • timerDelayInMilliseconds:請求合并的時間窗口旋廷,也就是出現(xiàn)第一個請求后鸠按,在該時間間隔內(nèi)的請求合并,超過則進入下一個時間窗口
  • requestCache.enabled:請求合并是否打開請求緩存

Thread Pool Properties 線程池參數(shù)

  • coreSize:線程池的大小
  • maximumSize:線程池的最大大小饶碘,只會在設(shè)置了allowMaximumSizeToDivergeFromCoreSize的情況下生效目尖,一般情況下和線程池大小相同。
  • maxQueueSize:-1代表使用SynchronousQueue熊镣,其它值代表LinkedBlockingQueue.這兩個隊列用于ThreadPoolExecutor
  • queueSizeRejectionThreshold:隊列拒絕服務(wù)的閾值
  • keepAliveTimeMinutes:如果線程池的最大值大于線程池的大小卑雁,那么這個配置用于回收多久沒被使用的線程。
  • allowMaximumSizeToDivergeFromCoreSize:線程池的最大值是否可以和線程池的值不一樣
  • metrics.rollingStats.timeInMilliseconds:設(shè)置統(tǒng)計滾動窗口的長度绪囱,以毫秒為單位测蹲。用于監(jiān)控和熔斷器。滾動窗口被分隔成桶(bucket)鬼吵。并進行滾動扣甲。 例如這個屬性設(shè)置10000ms,一個桶就是1s齿椅。
  • metrics.rollingStats.numBuckets:統(tǒng)計窗口的桶數(shù)量

3.2 Hystrix配置解析

  • Execution分組下的配置項琉挖,指定了方法執(zhí)行的隔離策略、超時限制等屬性涣脚。
  • Fallback分組下的配置項示辈,指定了最大并發(fā)限制,超過并發(fā)限制則走降級方法遣蚀。
  • Circuit Breaker分組下的配置項矾麻,指定了熔斷器的最小請求數(shù)、熔斷之后的重試間隔芭梯、造成熔斷的請求失敗率险耀。
  • Metrics分組下的配置項,主要是統(tǒng)計相關(guān)的參數(shù)玖喘,指定了滾動窗口的時間長度甩牺、桶數(shù)量、方法執(zhí)行時間的保留時間等累奈。這塊配置會比較難理解贬派。
  • Request Context分組下的配置項急但,指定了是否緩存請求結(jié)果、是否記錄日志赠群。
  • Collapser Properties分組下的配置項羊始,用來支持請求合并功能。當單個請求耗時很大的時候查描,可以使用請求合并的方式調(diào)用批量接口突委。設(shè)置最大請求數(shù),合并請求的等待時間冬三,配置請求結(jié)果是否需要緩存匀油。單個請求耗時很低的時候,不建議使用勾笆,反而會降低平均請求時延敌蚜。需要通過評估和計算得出哪種方案更合適窝爪。
  • Thread Pool Properties分組下的配置項目,指定了方法執(zhí)行的線程池的初始化參數(shù)蒲每。

4. 實現(xiàn)原理

Hystrix實現(xiàn)了熔斷機制、請求超時邀杏、限流降級、結(jié)果緩存望蜡、請求合并、統(tǒng)計脖律、線程池隔離等功能共同保障應(yīng)用的穩(wěn)定性谢肾。

先來看看官方的流程圖:


Flow Chart

分為以下步驟:

1.初始化HystrixCommand
2.執(zhí)行Command
3.是否需要走緩存獲取結(jié)果勒叠?
4.是否已經(jīng)開啟了熔斷?
5.信號量/線程池拒絕請求膏孟?
6.實際執(zhí)行方法
7.上報結(jié)果判斷是否開啟熔斷
8.執(zhí)行失敗走降級方法
9.執(zhí)行成功結(jié)果返回

處理執(zhí)行成功結(jié)果時使用了RxJava(觀察者模式)來傳遞事件,流程如下圖所示:


執(zhí)行結(jié)果返回

參考文獻

1.在項目中快速加入Netflix Hystrix特性
2.Hystrix入門指南
3.Hystrix配置簡單說明(官方文檔簡譯)
4.微服務(wù)(二)hystrix
5.Hystrix系列-5-Hystrix的資源隔離策略
6.通過HystrixCollapser合并請求提高應(yīng)用吞吐量
7.How it Works

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拌汇,一起剝皮案震驚了整個濱河市柒桑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌噪舀,老刑警劉巖魁淳,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件飘诗,死亡現(xiàn)場離奇詭異,居然都是意外死亡界逛,警方通過查閱死者的電腦和手機昆稿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來息拜,“玉大人溉潭,你說我怎么就攤上這事∩倨郏” “怎么了喳瓣?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赞别。 經(jīng)常有香客問我畏陕,道長,這世上最難降的妖魔是什么仿滔? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任惠毁,我火速辦了婚禮,結(jié)果婚禮上崎页,老公的妹妹穿的比我還像新娘鞠绰。我一直安慰自己,他們只是感情好实昨,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布洞豁。 她就那樣靜靜地躺著,像睡著了一般荒给。 火紅的嫁衣襯著肌膚如雪丈挟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天志电,我揣著相機與錄音曙咽,去河邊找鬼。 笑死挑辆,一個胖子當著我的面吹牛例朱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鱼蝉,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼洒嗤,長吁一口氣:“原來是場噩夢啊……” “哼渔隶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起间唉,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤呈野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后军掂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姆打,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年玛追,在試婚紗的時候發(fā)現(xiàn)自己被綠了痊剖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垒玲。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叮贩,靈堂內(nèi)的尸體忽然破棺而出佛析,到底是詐尸還是另有隱情,我是刑警寧澤捺萌,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布膘茎,位于F島的核電站,受9級特大地震影響态坦,放射性物質(zhì)發(fā)生泄漏棒拂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一壮锻、第九天 我趴在偏房一處隱蔽的房頂上張望猜绣。 院中可真熱鬧敬特,春花似錦、人聲如沸伟阔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽多搀。三九已至,卻和暖如春康铭,著一層夾襖步出監(jiān)牢的瞬間赌髓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工夷野, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匿沛,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓鳖孤,卻偏偏與公主長得像苏揣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子平匈,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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