摘要:斷路器原理斷路器在和執(zhí)行過程中起到至關重要的作用。其中通過來定義,每一個命令都需要有一個來標識,同時根據這個可以找到對應的斷路器實例。一個啥都不做的斷路器,它允許所有請求通過,并且斷路器始終處于閉合狀態(tài)斷路器的另一個實現類。
斷路器原理
斷路器在HystrixCommand和HystrixObservableCommand執(zhí)行過程中起到至關重要的作用。查看一下核心組件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(): 每個Hystrix命令的請求都通過它判斷是否被執(zhí)行(已經不再使用,使用attemptExecution()方法進行判斷)
attemptExecution(): 每個Hystrix命令的請求都通過它判斷是否被執(zhí)行
isOpen(): 返回當前斷路器是否打開
markSuccess(): 用來關閉斷路器
markNonSuccess: 用來打開斷路器
下面看一下該接口中的類:
Factory: 維護了一個Hystrix命令和HystrixCircuitBreaker的關系的集合ConcurrentHashMap
NoOpCircuitBreaker: 一個啥都不做的斷路器,它允許所有請求通過,并且斷路器始終處于閉合狀態(tài)
HystrixCircuitBreakerImpl:斷路器的另一個實現類。
HystrixCircuitBreakerImpl介紹在該類中定義了斷路器的五個核心對象:
HystrixCommandProperties properties:斷路器對應實例的屬性集合對象
HystrixCommandMetrics metrics:用來讓HystrixCommand記錄各類度量指標的對象
AtomicReference
AtomicLong circuitOpened:斷路器打開的時間戳,默認-1,表示斷路器未打開
AtomicReference
@Override public boolean isOpen() { if (properties.circuitBreakerForceOpen().get()) { return true; } if (properties.circuitBreakerForceClosed().get()) { return false; } return circuitOpened.get() >= 0; }
用來判斷斷路器是否打開或關閉。主要步驟有:
如果斷路器強制打開,返回true
如果斷路器強制關閉,返回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; } } }
該方法的主要邏輯有以下幾步:
如果斷路器強制打開,返回false,不允許放過請求
如果斷路器強制關閉,返回true,允許放過請求
如果斷路器是關閉狀態(tài),返回true,允許放過請求
判斷當前時間是否超過斷路器打開的時間加上滑動窗口的時間,如果沒有超過,返回false,不允許放過請求
如果沒有超過,如果斷路器是打開狀態(tài),并且設置斷路器狀態(tài)為半開狀態(tài)成功時,返回true,允許放過請求
如果失敗,則返回false,不允許放過請求
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); } }
該方法主要用來關閉斷路器,主要邏輯有以下幾步:
如果斷路器狀態(tài)是半開并且成功設置為關閉狀態(tài)時,執(zhí)行以下步驟。
重置度量指標對象
取消之前的訂閱,發(fā)起新的訂閱
設置斷路器的打開時間為-1
代碼地址spring-cloud-example
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76951.html
摘要:系統(tǒng)需要支持命令的撤銷。第步計算斷路器的健康度會將成功失敗拒絕超時等信息報告給斷路器,斷路器會維護一組計數器來統(tǒng)計這些數據。第步,當前命令的線程池請求隊列或者信號量被占滿的時候。 斷路由器模式 在分布式架構中,當某個服務單元發(fā)生故障之后,通過斷路由器的故障監(jiān)控(類似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間占用不釋放,避免了故障...
摘要:當服務宕機或者不可用時,即請求超時后會調用此方法。添加電影微服務啟動類電影微服務集成斷路器實現失敗快速響應,達到熔斷效果。 SpringCloud(第 014 篇)電影 Ribbon 微服務集成 Hystrix 斷路器實現失敗快速響應,達到熔斷效果 - 一、大致介紹 1、Hystrix 斷路器的原理很簡單,如同電力過載保護器。它可以實現快速失敗,如果它在一段時間內偵測到許多類似的錯誤,...
摘要:如果由包裝的工作不尊重,那么線程池中的線程將繼續(xù)它的工作,盡管客戶機已經收到了。這種行為可能會使線程池飽和,盡管負載正確釋放。 showImg(https://segmentfault.com/img/remote/1460000018779851); 簡介 在分布式環(huán)境中,許多服務依賴關系中的一些必然會失敗。Hystrix是一個庫,它通過添加延遲容忍和容錯邏輯來幫助您控制這些分布式服...
摘要:在艙壁模式中可以隔離每個遠程資源,并分配各自的線程池,使之互不影響。 springcloud 總集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本次用到全部代碼見文章最下方。 一、為什么要有客戶端彈性模式 ??所有的系統(tǒng)都會遇到故障,分布式系統(tǒng)單點故障概率更高。如何構建應用程序來應對故障,是每個軟件開發(fā)人員工作的關鍵部分。但是通...
摘要:為了保證服務高可用性,單個服務通常會進行集群部署。這時斷路器就派上用場了。當對某個服務的調用的不可用達到一個閥值默認是秒次斷路器將會被自動被打開。斷路打開后,方法可以直接返回一個預先設置的固定值。 公眾號: java樂園 在微服務架構中,根據業(yè)務需求拆分成一個個的微小服務,然后服務與服務之間可以相互RPC遠程調用。在Spring Cloud可以使用RestTemplate+Ribbo...
閱讀 1810·2021-11-24 09:39
閱讀 2295·2021-09-30 09:47
閱讀 4157·2021-09-22 15:57
閱讀 1881·2019-08-29 18:36
閱讀 3583·2019-08-29 12:21
閱讀 596·2019-08-29 12:17
閱讀 1271·2019-08-29 11:25
閱讀 731·2019-08-28 18:26