高可用服務(wù)架構(gòu)設(shè)計(jì)(10)-Hystrix隔離策略細(xì)粒度控制

0 Github

資源隔離兩種策略

  • 線程池隔離
  • 信號(hào)量隔離

對(duì)于資源隔離,做更加深入一些的講解扛稽,除了可以選擇隔離策略,對(duì)選擇的隔離策略,可以做一定的細(xì)粒度的控制

1 execution.isolation.strategy

image

指定HystrixCommand.run()的資源隔離策略

  • THREAD
    基于線程池
// to use thread isolation
HystrixCommandProperties.Setter()
   .withExecutionIsolationStrategy(ExecutionIsolationStrategy.THREAD)
  • SEMAPHORE
    基于信號(hào)量// to use semaphore isolation
    HystrixCommandProperties.Setter()
    .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)線程池機(jī)制谜疤,每個(gè)command運(yùn)行在一個(gè)線程中,限流是通過(guò)線程池的大小來(lái)控制的
    信號(hào)量機(jī)制,command是運(yùn)行在調(diào)用線程中夷磕,但是通過(guò)信號(hào)量的容量來(lái)進(jìn)行限流

如何在線程池和信號(hào)量之間做選擇呢履肃?

默認(rèn)的策略為線程池

線程池其實(shí)最大的好處就是對(duì)于網(wǎng)絡(luò)訪問(wèn)請(qǐng)求,若超時(shí)坐桩,可以避免調(diào)用線程阻塞住

而使用信號(hào)量的場(chǎng)景尺棋,通常是針對(duì)超大并發(fā)量的場(chǎng)景下,每個(gè)服務(wù)實(shí)例每秒都幾百的QPS

此時(shí)用線程池绵跷,線程一般不會(huì)太多膘螟,可能撐不住那么高的并發(fā)

要撐住,可能要耗費(fèi)大量的線程資源碾局,那么就是用信號(hào)量荆残,來(lái)限流保護(hù)

一般用信號(hào)量常見(jiàn)于那種基于純內(nèi)存的一些業(yè)務(wù)邏輯服務(wù),而不涉及到任何網(wǎng)絡(luò)訪問(wèn)請(qǐng)求

netflix有100+的command運(yùn)行在40+的線程池中净当,只有少數(shù)command是不運(yùn)行在線程池中的内斯,就是從純內(nèi)存中獲取一些元數(shù)據(jù),或者是對(duì)多個(gè)command包裝起來(lái)的facacde command像啼,是用信號(hào)量限流的

2 command名稱 & command組

線程池隔離嘿期,依賴服務(wù)->接口->線程池魁莉,如何來(lái)劃分

每個(gè)command随闺,都可以設(shè)置一個(gè)自己的名稱,同時(shí)可以設(shè)置一個(gè)自己的組

private static final Setter cachedSetter = 
    Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
        .andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"));    

public CommandHelloWorld(String name) {
    super(cachedSetter);
    this.name = name;
}
  • command group
    一個(gè)非常重要的概念爆班,默認(rèn)情況下甚颂,因?yàn)榫褪峭ㄟ^(guò)command group來(lái)定義一個(gè)線程池的蜜猾,而且還會(huì)通過(guò)command group來(lái)聚合一些監(jiān)控和報(bào)警信息

同一個(gè)command group中的請(qǐng)求,都會(huì)進(jìn)入同一個(gè)線程池中

3 command線程池

ThreadPoolKey代表了一個(gè)HystrixThreadPool振诬,用來(lái)進(jìn)行統(tǒng)一監(jiān)控蹭睡,統(tǒng)計(jì),緩存

image

默認(rèn)的threadpool key就是command group名稱

image

每個(gè)command都會(huì)跟它的ThreadPoolKey對(duì)應(yīng)的ThreadPool綁定

如果不想直接用command group赶么,也可以手動(dòng)設(shè)置thread pool name

public CommandHelloWorld(String name) {
    super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
            .andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"))
            .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool")));
    this.name = name;
}

command threadpool => command group => command key

  • command key


    image

    代表了一類command肩豁,代表底層的依賴服務(wù)的一個(gè)接口

  • command group


    image

    代表了某一個(gè)底層的依賴服務(wù),合理辫呻,一個(gè)依賴服務(wù)可能會(huì)暴露出來(lái)多個(gè)接口清钥,每個(gè)接口就是一個(gè)command key

command group

在邏輯上去組織起來(lái)一堆command key的調(diào)用,統(tǒng)計(jì)信息放闺,成功次數(shù)祟昭,timeout超時(shí)次數(shù),失敗次數(shù)怖侦,可以看到某一個(gè)服務(wù)整體的一些訪問(wèn)情況

推薦是根據(jù)一個(gè)服務(wù)去劃分出一個(gè)線程池篡悟,command key默認(rèn)都是屬于同一個(gè)線程池的

比如說(shuō)你以一個(gè)服務(wù)為粒度谜叹,估算出來(lái)這個(gè)服務(wù)每秒的所有接口加起來(lái)的整體QPS在100左右

你調(diào)用那個(gè)服務(wù)的當(dāng)前服務(wù),部署了10個(gè)服務(wù)實(shí)例搬葬,每個(gè)服務(wù)實(shí)例上荷腊,其實(shí)用這個(gè)command group對(duì)應(yīng)這個(gè)服務(wù),給一個(gè)線程池急凰,量大概在10個(gè)左右停局,就可以了,你對(duì)整個(gè)服務(wù)的整體的訪問(wèn)QPS大概在每秒100左右

一般來(lái)說(shuō)香府,command group是用來(lái)在邏輯上組合一堆command的

舉個(gè)例子董栽,對(duì)于一個(gè)服務(wù)中的某個(gè)功能模塊來(lái)說(shuō),希望將這個(gè)功能模塊內(nèi)的所有command放在一個(gè)group中企孩,那么在監(jiān)控和報(bào)警的時(shí)候可以放一起看

command group锭碳,對(duì)應(yīng)了一個(gè)服務(wù),但是這個(gè)服務(wù)暴露出來(lái)的幾個(gè)接口勿璃,訪問(wèn)量很不一樣擒抛,差異非常之大

你可能就希望在這個(gè)服務(wù)command group內(nèi)部,包含的對(duì)應(yīng)多個(gè)接口的command key补疑,做一些細(xì)粒度的資源隔離

對(duì)同一個(gè)服務(wù)的不同接口歧沪,都使用不同的線程池

command key -> command group

command key -> 自己的threadpool key

邏輯上來(lái)說(shuō),多個(gè)command key屬于一個(gè)command group莲组,在做統(tǒng)計(jì)的時(shí)候诊胞,會(huì)放在一起統(tǒng)計(jì)

每個(gè)command key有自己的線程池,每個(gè)接口有自己的線程池锹杈,去做資源隔離和限流

但對(duì)于thread pool資源隔離來(lái)說(shuō)撵孤,可能是希望能夠拆分的更加一致一些,比如在一個(gè)功能模塊內(nèi)竭望,對(duì)不同的請(qǐng)求可以使用不同的thread pool

command group一般來(lái)說(shuō)邪码,可以是對(duì)應(yīng)一個(gè)服務(wù),多個(gè)command key對(duì)應(yīng)這個(gè)服務(wù)的多個(gè)接口咬清,多個(gè)接口的調(diào)用共享同一個(gè)線程池

如果說(shuō)你的command key闭专,要用自己的線程池,可以定義自己的threadpool key旧烧,就ok了

4 coreSize

設(shè)置線程池的大小影钉,默認(rèn)是10

HystrixThreadPoolProperties.Setter()
                           .withCoreSize(int value)

一般來(lái)說(shuō),用這個(gè)默認(rèn)的10個(gè)線程大小就夠了

5 queueSizeRejectionThreshold

控制queue滿后reject的threshold粪滤,因?yàn)閙axQueueSize不允許熱修改斧拍,因此提供這個(gè)參數(shù)可以熱修改,控制隊(duì)列的最大值

HystrixCommand在提交到線程池之前杖小,其實(shí)會(huì)先進(jìn)入一個(gè)隊(duì)列中肆汹,這個(gè)隊(duì)列滿了之后,才會(huì)reject

默認(rèn)值是5

HystrixThreadPoolProperties.Setter()
   .withQueueSizeRejectionThreshold(int value)
  • 線程池+queue的工作原理
    image

6 isolation.semaphore.maxConcurrentRequests

設(shè)置使用SEMAPHORE隔離策略的時(shí)候予权,允許訪問(wèn)的最大并發(fā)量昂勉,超過(guò)這個(gè)最大并發(fā)量,請(qǐng)求直接被reject

這個(gè)并發(fā)量的設(shè)置扫腺,跟線程池大小的設(shè)置岗照,應(yīng)該是類似的

但是基于信號(hào)量的話,性能會(huì)好很多笆环,而且hystrix框架本身的開(kāi)銷會(huì)小很多

默認(rèn)值是10攒至,設(shè)置的小一些,否則因?yàn)樾盘?hào)量是基于調(diào)用線程去執(zhí)行command的躁劣,而且不能從timeout中抽離迫吐,因此一旦設(shè)置的太大,而且有延時(shí)發(fā)生账忘,可能瞬間導(dǎo)致tomcat本身的線程資源本占滿

image

參考

  • 《Java工程師面試突擊第1季-中華石杉老師》
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末志膀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鳖擒,更是在濱河造成了極大的恐慌溉浙,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒋荚,死亡現(xiàn)場(chǎng)離奇詭異戳稽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)期升,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)广鳍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人吓妆,你說(shuō)我怎么就攤上這事赊时。” “怎么了行拢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵祖秒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我舟奠,道長(zhǎng)竭缝,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任沼瘫,我火速辦了婚禮抬纸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耿戚。我一直安慰自己湿故,他們只是感情好阿趁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著坛猪,像睡著了一般脖阵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墅茉,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天命黔,我揣著相機(jī)與錄音,去河邊找鬼就斤。 笑死悍募,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洋机。 我是一名探鬼主播坠宴,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼槐秧!你這毒婦竟也來(lái)了啄踊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刁标,失蹤者是張志新(化名)和其女友劉穎颠通,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體膀懈,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顿锰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了启搂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硼控。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胳赌,靈堂內(nèi)的尸體忽然破棺而出牢撼,到底是詐尸還是另有隱情,我是刑警寧澤疑苫,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布熏版,位于F島的核電站,受9級(jí)特大地震影響捍掺,放射性物質(zhì)發(fā)生泄漏撼短。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一挺勿、第九天 我趴在偏房一處隱蔽的房頂上張望曲横。 院中可真熱鬧,春花似錦不瓶、人聲如沸禾嫉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夭织。三九已至吭露,卻和暖如春吠撮,著一層夾襖步出監(jiān)牢的瞬間尊惰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工泥兰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弄屡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓鞋诗,卻偏偏與公主長(zhǎng)得像膀捷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子削彬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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