摘要:斷路器原理斷路器在和執(zhí)行過(guò)程中起到至關(guān)重要的作用。其中通過(guò)來(lái)定義,每一個(gè)命令都需要有一個(gè)來(lái)標(biāo)識(shí),同時(shí)根據(jù)這個(gè)可以找到對(duì)應(yīng)的斷路器實(shí)例。一個(gè)啥都不做的斷路器,它允許所有請(qǐng)求通過(guò),并且斷路器始終處于閉合狀態(tài)斷路器的另一個(gè)實(shí)現(xiàn)類。
斷路器原理
斷路器在HystrixCommand和HystrixObservableCommand執(zhí)行過(guò)程中起到至關(guān)重要的作用。查看一下核心組件HystrixCircuitBreaker
package com.netflix.hystrix; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import com.netflix.hystrix.HystrixCommandMetrics.HealthCounts; import rx.Subscriber; import rx.Subscription; public interface HystrixCircuitBreaker { boolean allowRequest(); boolean isOpen(); void markSuccess(); void markNonSuccess(); boolean attemptExecution(); class Factory { // String is HystrixCommandKey.name() (we can"t use HystrixCommandKey directly as we can"t guarantee it implements hashcode/equals correctly) private static ConcurrentHashMapcircuitBreakersByCommand = new ConcurrentHashMap (); } class HystrixCircuitBreakerImpl implements HystrixCircuitBreaker { } static class NoOpCircuitBreaker implements HystrixCircuitBreaker { } }
下面先看一下該接口的抽象方法:
allowRequest(): 每個(gè)Hystrix命令的請(qǐng)求都通過(guò)它判斷是否被執(zhí)行(已經(jīng)不再使用,使用attemptExecution()方法進(jìn)行判斷)
attemptExecution(): 每個(gè)Hystrix命令的請(qǐng)求都通過(guò)它判斷是否被執(zhí)行
isOpen(): 返回當(dāng)前斷路器是否打開(kāi)
markSuccess(): 用來(lái)關(guān)閉斷路器
markNonSuccess: 用來(lái)打開(kāi)斷路器
下面看一下該接口中的類:
Factory: 維護(hù)了一個(gè)Hystrix命令和HystrixCircuitBreaker的關(guān)系的集合ConcurrentHashMap
NoOpCircuitBreaker: 一個(gè)啥都不做的斷路器,它允許所有請(qǐng)求通過(guò),并且斷路器始終處于閉合狀態(tài)
HystrixCircuitBreakerImpl:斷路器的另一個(gè)實(shí)現(xiàn)類。
HystrixCircuitBreakerImpl介紹在該類中定義了斷路器的五個(gè)核心對(duì)象:
HystrixCommandProperties properties:斷路器對(duì)應(yīng)實(shí)例的屬性集合對(duì)象
HystrixCommandMetrics metrics:用來(lái)讓HystrixCommand記錄各類度量指標(biāo)的對(duì)象
AtomicReference
AtomicLong circuitOpened:斷路器打開(kāi)的時(shí)間戳,默認(rèn)-1,表示斷路器未打開(kāi)
AtomicReference
@Override public boolean isOpen() { if (properties.circuitBreakerForceOpen().get()) { return true; } if (properties.circuitBreakerForceClosed().get()) { return false; } return circuitOpened.get() >= 0; }
用來(lái)判斷斷路器是否打開(kāi)或關(guān)閉。主要步驟有:
如果斷路器強(qiáng)制打開(kāi),返回true
如果斷路器強(qiáng)制關(guān)閉,返回false
判斷circuitOpened的值,如果大于等于0,返回true, 否則返回false
attemptExecution方法介紹private boolean isAfterSleepWindow() { final long circuitOpenTime = circuitOpened.get(); final long currentTime = System.currentTimeMillis(); final long sleepWindowTime = properties.circuitBreakerSleepWindowInMilliseconds().get(); return currentTime > circuitOpenTime + sleepWindowTime; } @Override public boolean attemptExecution() { if (properties.circuitBreakerForceOpen().get()) { return false; } if (properties.circuitBreakerForceClosed().get()) { return true; } if (circuitOpened.get() == -1) { return true; } else { if (isAfterSleepWindow()) { if (status.compareAndSet(Status.OPEN, Status.HALF_OPEN)) { //only the first request after sleep window should execute return true; } else { return false; } } else { return false; } } }
該方法的主要邏輯有以下幾步:
如果斷路器強(qiáng)制打開(kāi),返回false,不允許放過(guò)請(qǐng)求
如果斷路器強(qiáng)制關(guān)閉,返回true,允許放過(guò)請(qǐng)求
如果斷路器是關(guān)閉狀態(tài),返回true,允許放過(guò)請(qǐng)求
判斷當(dāng)前時(shí)間是否超過(guò)斷路器打開(kāi)的時(shí)間加上滑動(dòng)窗口的時(shí)間,如果沒(méi)有超過(guò),返回false,不允許放過(guò)請(qǐng)求
如果沒(méi)有超過(guò),如果斷路器是打開(kāi)狀態(tài),并且設(shè)置斷路器狀態(tài)為半開(kāi)狀態(tài)成功時(shí),返回true,允許放過(guò)請(qǐng)求
如果失敗,則返回false,不允許放過(guò)請(qǐng)求
markSuccess方法@Override public void markSuccess() { if (status.compareAndSet(Status.HALF_OPEN, Status.CLOSED)) { //This thread wins the race to close the circuit - it resets the stream to start it over from 0 metrics.resetStream(); Subscription previousSubscription = activeSubscription.get(); if (previousSubscription != null) { previousSubscription.unsubscribe(); } Subscription newSubscription = subscribeToStream(); activeSubscription.set(newSubscription); circuitOpened.set(-1L); } }
該方法主要用來(lái)關(guān)閉斷路器,主要邏輯有以下幾步:
如果斷路器狀態(tài)是半開(kāi)并且成功設(shè)置為關(guān)閉狀態(tài)時(shí),執(zhí)行以下步驟。
重置度量指標(biāo)對(duì)象
取消之前的訂閱,發(fā)起新的訂閱
設(shè)置斷路器的打開(kāi)時(shí)間為-1
代碼地址spring-cloud-example
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/76951.html
摘要:系統(tǒng)需要支持命令的撤銷。第步計(jì)算斷路器的健康度會(huì)將成功失敗拒絕超時(shí)等信息報(bào)告給斷路器,斷路器會(huì)維護(hù)一組計(jì)數(shù)器來(lái)統(tǒng)計(jì)這些數(shù)據(jù)。第步,當(dāng)前命令的線程池請(qǐng)求隊(duì)列或者信號(hào)量被占滿的時(shí)候。 斷路由器模式 在分布式架構(gòu)中,當(dāng)某個(gè)服務(wù)單元發(fā)生故障之后,通過(guò)斷路由器的故障監(jiān)控(類似熔斷保險(xiǎn)絲),向調(diào)用方返回一個(gè)錯(cuò)誤響應(yīng),而不是長(zhǎng)時(shí)間的等待。這樣就不會(huì)使得線程因調(diào)用故障服務(wù)被長(zhǎng)時(shí)間占用不釋放,避免了故障...
摘要:當(dāng)服務(wù)宕機(jī)或者不可用時(shí),即請(qǐng)求超時(shí)后會(huì)調(diào)用此方法。添加電影微服務(wù)啟動(dòng)類電影微服務(wù)集成斷路器實(shí)現(xiàn)失敗快速響應(yīng),達(dá)到熔斷效果。 SpringCloud(第 014 篇)電影 Ribbon 微服務(wù)集成 Hystrix 斷路器實(shí)現(xiàn)失敗快速響應(yīng),達(dá)到熔斷效果 - 一、大致介紹 1、Hystrix 斷路器的原理很簡(jiǎn)單,如同電力過(guò)載保護(hù)器。它可以實(shí)現(xiàn)快速失敗,如果它在一段時(shí)間內(nèi)偵測(cè)到許多類似的錯(cuò)誤,...
摘要:如果由包裝的工作不尊重,那么線程池中的線程將繼續(xù)它的工作,盡管客戶機(jī)已經(jīng)收到了。這種行為可能會(huì)使線程池飽和,盡管負(fù)載正確釋放。 showImg(https://segmentfault.com/img/remote/1460000018779851); 簡(jiǎn)介 在分布式環(huán)境中,許多服務(wù)依賴關(guān)系中的一些必然會(huì)失敗。Hystrix是一個(gè)庫(kù),它通過(guò)添加延遲容忍和容錯(cuò)邏輯來(lái)幫助您控制這些分布式服...
摘要:在艙壁模式中可以隔離每個(gè)遠(yuǎn)程資源,并分配各自的線程池,使之互不影響。 springcloud 總集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本次用到全部代碼見(jiàn)文章最下方。 一、為什么要有客戶端彈性模式 ??所有的系統(tǒng)都會(huì)遇到故障,分布式系統(tǒng)單點(diǎn)故障概率更高。如何構(gòu)建應(yīng)用程序來(lái)應(yīng)對(duì)故障,是每個(gè)軟件開(kāi)發(fā)人員工作的關(guān)鍵部分。但是通...
摘要:為了保證服務(wù)高可用性,單個(gè)服務(wù)通常會(huì)進(jìn)行集群部署。這時(shí)斷路器就派上用場(chǎng)了。當(dāng)對(duì)某個(gè)服務(wù)的調(diào)用的不可用達(dá)到一個(gè)閥值默認(rèn)是秒次斷路器將會(huì)被自動(dòng)被打開(kāi)。斷路打開(kāi)后,方法可以直接返回一個(gè)預(yù)先設(shè)置的固定值。 公眾號(hào): java樂(lè)園 在微服務(wù)架構(gòu)中,根據(jù)業(yè)務(wù)需求拆分成一個(gè)個(gè)的微小服務(wù),然后服務(wù)與服務(wù)之間可以相互RPC遠(yuǎn)程調(diào)用。在Spring Cloud可以使用RestTemplate+Ribbo...
閱讀 1896·2021-11-24 09:39
閱讀 2355·2021-09-30 09:47
閱讀 4255·2021-09-22 15:57
閱讀 1996·2019-08-29 18:36
閱讀 3644·2019-08-29 12:21
閱讀 653·2019-08-29 12:17
閱讀 1321·2019-08-29 11:25
閱讀 788·2019-08-28 18:26