hystrix使用總結(jié)

Hystrix是一個(gè)用于處理分布式系統(tǒng)的延遲和容錯(cuò)的開源庫宋欺,可是實(shí)現(xiàn)服務(wù)降級(jí)艺挪,服務(wù)熔斷,服務(wù)限流等功能鸿染,目前已經(jīng)停止更新指蚜,進(jìn)入維護(hù)

依賴

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

服務(wù)降級(jí)

當(dāng)某個(gè)服務(wù)出現(xiàn)異常或者這長時(shí)間無響應(yīng)牡昆,則會(huì)使調(diào)用此服務(wù)的其他服務(wù)造成不好的影響姚炕,返回的信息也不友好摊欠。服務(wù)降級(jí)就是解決這個(gè)問題,當(dāng)一個(gè)服務(wù)超出響應(yīng)時(shí)間或者異常柱宦,則會(huì)執(zhí)行事先設(shè)計(jì)好的方法來‘兜底’

使用前些椒,要在主程序上加上@EnableHystrix(里邊包括了@EnableCircuitBreaker)注解開啟功能

hystrix注解開發(fā)使用很方便,如下

@Service
public class PaymentService {
    //              出現(xiàn)問題調(diào)用的方法
    @HystrixCommand(fallbackMethod = "paymentInfoTimeOutHandle",commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000") // 服務(wù)降級(jí)時(shí)間
    })
    public String paymentInfoTimeOut(Integer id) {
        try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
        return "線程池:  "+Thread.currentThread().getName()+" id:  "+id;
    }

    public String paymentInfoTimeOutHandle(Integer id) {
       return "線程池:  "+Thread.currentThread().getName()+" id:  "+id+"\t  系統(tǒng)繁忙 o(╥﹏╥)o";
    }
}

paymentInfoTimeOut方法超時(shí)或拋出異常掸刊,則會(huì)執(zhí)行fallbackMethod指定

與feign集成的使用

配置文件加入

feign:
  hystrix:
    enabled: true

這個(gè)配置的作用是:Feign將使用斷路器包裝所有方法免糕,也就是將@FeignClient標(biāo)記的那個(gè)service接口下所有的方法進(jìn)行了hystrix包裝(似于在這些方法上加了一個(gè)@HystrixCommand),這些方法會(huì)有一個(gè)1s的默認(rèn)超時(shí)時(shí)間忧侧,超過就會(huì)fallback石窑,想要修改的話可以在yml中配置

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 #換成了三秒

集成使用:


@Component
@FeignClient(value = "payment",fallback = FeignHystrixService.class)
public interface FeignService {

    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_TimeOut(@PathVariable("id") Integer id);

}

fallback 指定一個(gè)FeignService 接口的實(shí)現(xiàn)類,每個(gè)方法的實(shí)現(xiàn)就是默認(rèn)的兜底方法蚓炬,如下

@Component
public class FeignHystrixService implements FeignService{
    @Override
    public String paymentInfo_OK(Integer id) {
        return "超時(shí)了松逊。。肯夏。o(╥﹏╥)o";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "超時(shí)了经宏。。驯击。o(╥﹏╥)o";
    }
}

服務(wù)熔斷

熔斷機(jī)制是應(yīng)對(duì)雪崩效應(yīng)的一種微服務(wù)鏈路保護(hù)機(jī)制,當(dāng)一段時(shí)間內(nèi)烁兰,服務(wù)降級(jí)觸發(fā)的次數(shù)超過一定百分比,就會(huì)觸發(fā)熔斷徊都,熔斷期間沪斟,所有的請(qǐng)求無論是否超時(shí)或異常,都會(huì)走降級(jí)方法暇矫,經(jīng)過規(guī)定窗口期后主之,hystrix會(huì)自動(dòng)處理一些請(qǐng)求做嘗試,然后自動(dòng)恢復(fù)

使用

   @HystrixCommand(fallbackMethod = "paymentInfoTimeOutHandle",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否開啟斷路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 請(qǐng)求次數(shù)
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 時(shí)間窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失敗率達(dá)到多少后跳閘
    })
    public String paymentCircuitBreaker(Integer id) {
        if(id < 0) {
            throw new RuntimeException("id 不能負(fù)數(shù)");
        }
        String serialNumber = UUID.randomUUID().toString();

        return Thread.currentThread().getName()+"\t"+"調(diào)用成功袱耽,流水號(hào): " + serialNumber;
    }


    public String paymentInfoTimeOutHandle(Integer id) {
       return "線程池:  "+Thread.currentThread().getName()+" id:  "+id+"\t  系統(tǒng)繁忙 o(╥﹏╥)o";
    }

之后可以啟動(dòng)服務(wù)試一下杀餐,傳入-1參數(shù)多次,會(huì)觸發(fā)熔斷朱巨,但在此輸入正數(shù)id依然會(huì)調(diào)用降級(jí)方法,之后會(huì)自動(dòng)恢復(fù)

關(guān)于HystrixProperty的配置

 @HystrixCommand(fallbackMethod = "fallbackMethod",
                 groupKey = "strGroupCommand",
                 commandKey = "strCommand",
                 threadPoolKey = "strThreadPool",

                 commandProperties = {
                     // 設(shè)置隔離策略枉长,THREAD 表示線程池 SEMAPHORE:信號(hào)池隔離
                     @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                     // 當(dāng)隔離策略選擇信號(hào)池隔離的時(shí)候冀续,用來設(shè)置信號(hào)池的大小(最大并發(fā)數(shù))
                     @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),
                     // 配置命令執(zhí)行的超時(shí)時(shí)間
                     @HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "10"),
                     // 是否啟用超時(shí)時(shí)間
                     @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
                     // 執(zhí)行超時(shí)的時(shí)候是否中斷
                     @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),

                     // 執(zhí)行被取消的時(shí)候是否中斷
                     @HystrixProperty(name = "execution.isolation.thread.interruptOnCancel", value = "true"),
                     // 允許回調(diào)方法執(zhí)行的最大并發(fā)數(shù)
                     @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10"),
                     // 服務(wù)降級(jí)是否啟用必峰,是否執(zhí)行回調(diào)函數(shù)
                     @HystrixProperty(name = "fallback.enabled", value = "true"),
                     // 是否啟用斷路器
                     @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                     // 該屬性用來設(shè)置在滾動(dòng)時(shí)間窗中洪唐,斷路器熔斷的最小請(qǐng)求數(shù)。例如吼蚁,默認(rèn)該值為 20 的時(shí)候凭需,如果滾動(dòng)時(shí)間窗(默認(rèn)10秒)內(nèi)僅收到了19個(gè)請(qǐng)求问欠, 即使這19個(gè)請(qǐng)求都失敗了,斷路器也不會(huì)打開粒蜈。
                     @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),

                     // 該屬性用來設(shè)置在滾動(dòng)時(shí)間窗中顺献,表示在滾動(dòng)時(shí)間窗中,在請(qǐng)求數(shù)量超過 circuitBreaker.requestVolumeThreshold 的情況下枯怖,如果錯(cuò)誤請(qǐng)求數(shù)的百分比超過50, 就把斷路器設(shè)置為 "打開" 狀態(tài)注整,否則就設(shè)置為 "關(guān)閉" 狀態(tài)。
                     @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                     // 該屬性用來設(shè)置當(dāng)斷路器打開之后的休眠時(shí)間窗度硝。 休眠時(shí)間窗結(jié)束之后肿轨,會(huì)將斷路器置為 "半開" 狀態(tài),嘗試熔斷的請(qǐng)求命令蕊程,如果依然失敗就將斷路器繼續(xù)設(shè)置為 "打開" 狀態(tài)椒袍,如果成功就設(shè)置為 "關(guān)閉" 狀態(tài)。
                     @HystrixProperty(name = "circuitBreaker.sleepWindowinMilliseconds", value = "5000"),
                     // 斷路器強(qiáng)制打開
                     @HystrixProperty(name = "circuitBreaker.forceOpen", value = "false"),
                     // 斷路器強(qiáng)制關(guān)閉
                     @HystrixProperty(name = "circuitBreaker.forceClosed", value = "false"),
                     // 滾動(dòng)時(shí)間窗設(shè)置藻茂,該時(shí)間用于斷路器判斷健康度時(shí)需要收集信息的持續(xù)時(shí)間
                     @HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds", value = "10000"),

                     // 該屬性用來設(shè)置滾動(dòng)時(shí)間窗統(tǒng)計(jì)指標(biāo)信息時(shí)劃分"桶"的數(shù)量驹暑,斷路器在收集指標(biāo)信息的時(shí)候會(huì)根據(jù)設(shè)置的時(shí)間窗長度拆分成多個(gè) "桶" 來累計(jì)各度量值,每個(gè)"桶"記錄了一段時(shí)間內(nèi)的采集指標(biāo)捌治。
                     // 比如 10 秒內(nèi)拆分成 10 個(gè)"桶"收集這樣岗钩,所以 timeinMilliseconds 必須能被 numBuckets 整除。否則會(huì)拋異常
                     @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10"),
                     // 該屬性用來設(shè)置對(duì)命令執(zhí)行的延遲是否使用百分位數(shù)來跟蹤和計(jì)算肖油。如果設(shè)置為 false, 那么所有的概要統(tǒng)計(jì)都將返回 -1兼吓。
                     @HystrixProperty(name = "metrics.rollingPercentile.enabled", value = "false"),
                     // 該屬性用來設(shè)置百分位統(tǒng)計(jì)的滾動(dòng)窗口的持續(xù)時(shí)間,單位為毫秒森枪。
                     @HystrixProperty(name = "metrics.rollingPercentile.timeInMilliseconds", value = "60000"),
                     // 該屬性用來設(shè)置百分位統(tǒng)計(jì)滾動(dòng)窗口中使用 “ 桶 ”的數(shù)量视搏。
                     @HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "60000"),
                     // 該屬性用來設(shè)置在執(zhí)行過程中每個(gè) “桶” 中保留的最大執(zhí)行次數(shù)。如果在滾動(dòng)時(shí)間窗內(nèi)發(fā)生超過該設(shè)定值的執(zhí)行次數(shù)县袱,
                     // 就從最初的位置開始重寫浑娜。例如,將該值設(shè)置為100, 滾動(dòng)窗口為10秒式散,若在10秒內(nèi)一個(gè) “桶 ”中發(fā)生了500次執(zhí)行筋遭,
                     // 那么該 “桶” 中只保留 最后的100次執(zhí)行的統(tǒng)計(jì)。另外暴拄,增加該值的大小將會(huì)增加內(nèi)存量的消耗漓滔,并增加排序百分位數(shù)所需的計(jì)算時(shí)間。
                     @HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "100"),

                     // 該屬性用來設(shè)置采集影響斷路器狀態(tài)的健康快照(請(qǐng)求的成功乖篷、 錯(cuò)誤百分比)的間隔等待時(shí)間响驴。
                     @HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),
                     // 是否開啟請(qǐng)求緩存
                     @HystrixProperty(name = "requestCache.enabled", value = "true"),
                     // HystrixCommand的執(zhí)行和事件是否打印日志到 HystrixRequestLog 中
                     @HystrixProperty(name = "requestLog.enabled", value = "true"),

                 },
                 threadPoolProperties = {
                     // 該參數(shù)用來設(shè)置執(zhí)行命令線程池的核心線程數(shù),該值也就是命令執(zhí)行的最大并發(fā)量
                     @HystrixProperty(name = "coreSize", value = "10"),
                     // 該參數(shù)用來設(shè)置線程池的最大隊(duì)列大小撕蔼。當(dāng)設(shè)置為 -1 時(shí)豁鲤,線程池將使用 SynchronousQueue 實(shí)現(xiàn)的隊(duì)列秽誊,否則將使用 LinkedBlockingQueue 實(shí)現(xiàn)的隊(duì)列。
                     @HystrixProperty(name = "maxQueueSize", value = "-1"),
                     // 該參數(shù)用來為隊(duì)列設(shè)置拒絕閾值琳骡。 通過該參數(shù)锅论, 即使隊(duì)列沒有達(dá)到最大值也能拒絕請(qǐng)求。
                     // 該參數(shù)主要是對(duì) LinkedBlockingQueue 隊(duì)列的補(bǔ)充,因?yàn)?LinkedBlockingQueue 隊(duì)列不能動(dòng)態(tài)修改它的對(duì)象大小日熬,而通過該屬性就可以調(diào)整拒絕請(qǐng)求的隊(duì)列大小了棍厌。
                     @HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),
                 }
                )
 public String doSomething() {
    ...
 }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市竖席,隨后出現(xiàn)的幾起案子耘纱,更是在濱河造成了極大的恐慌,老刑警劉巖毕荐,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件束析,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡憎亚,警方通過查閱死者的電腦和手機(jī)员寇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來第美,“玉大人蝶锋,你說我怎么就攤上這事∈餐” “怎么了扳缕?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長别威。 經(jīng)常有香客問我躯舔,道長,這世上最難降的妖魔是什么省古? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任粥庄,我火速辦了婚禮,結(jié)果婚禮上豺妓,老公的妹妹穿的比我還像新娘惜互。我一直安慰自己,他們只是感情好琳拭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布载佳。 她就那樣靜靜地躺著,像睡著了一般臀栈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挠乳,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天权薯,我揣著相機(jī)與錄音姑躲,去河邊找鬼。 笑死盟蚣,一個(gè)胖子當(dāng)著我的面吹牛黍析,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屎开,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼阐枣,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了奄抽?” 一聲冷哼從身側(cè)響起蔼两,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逞度,沒想到半個(gè)月后额划,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡档泽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年俊戳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馆匿。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抑胎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渐北,到底是詐尸還是另有隱情阿逃,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布腔稀,位于F島的核電站盆昙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏焊虏。R本人自食惡果不足惜淡喜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诵闭。 院中可真熱鬧炼团,春花似錦、人聲如沸疏尿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褥琐。三九已至锌俱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敌呈,已是汗流浹背贸宏。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工造寝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吭练。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓诫龙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鲫咽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子签赃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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