• <noscript id="yywya"><kbd id="yywya"></kbd></noscript>
  • 發布時間:2020-10-05 17:01 原文鏈接: 斷路器模式概述(一)

    軟件系統對運行在不同進程或者網路中不同的機器的軟件進行遠程調用是很常見的。內存中調用和遠程調用之間的一個主要區別是,遠程調用可能會失敗,或者在達到某個超時限制之前掛起而沒有響應。更糟糕的是,如果一個響應延遲的服務提供方上有許多調用者,那么您可能會耗盡關鍵資源,導致跨多個系統的連鎖故障。Michael Nygard在他的優秀著作《發布》中推廣了斷路器模式,以防止這種災難性的連鎖故障。

    斷路器的基本原理很簡單。您將一個受保護的函數調用封裝在一個斷路器對象中,該斷路器對象監視故障。一旦故障達到某個閾值,斷路器就會跳閘,所有對斷路器的繼續調用都會返回一個錯誤,受保護的調用也不會繼續。如果斷路器跳閘,您通常還需要通過監視器進行警報。

    下面是Ruby寫的一個簡單示例,用于防止超時。

    我使用block (Lambda)設置了斷路器,它是受保護的調用。

    cb = CircuitBreaker.new {|arg| @supplier.func arg}

    斷路器存儲block,初始化各種參數(閾值、超時和監視功能),并將斷路器重置為關閉狀態。

    class CircuitBreaker...

    attr_accessor :invocation_timeout, :failure_threshold, :monitor

    def initialize &block

    @circuit = block

    @invocation_timeout = 0.01

    @failure_threshold = 5

    @monitor = acquire_monitor

    reset

    end

    如果線路關閉,則調用斷路器將調用底層block,如果打開則返回錯誤

    # client code

    aCircuitBreaker.call(5)

    class CircuitBreaker...

    def call args

    case state

    when :closed

    begin

    do_call args

    rescue Timeout::Error

    record_failure

    raise $!

    end

    when :open then raise CircuitBreaker::Open

    else raise "Unreachable Code"

    end

    end

    def do_call args

    result = Timeout::timeout(@invocation_timeout) do

    @circuit.call args

    end

    reset

    return result

    end

    如果我們調用超時,我們故障計數器計數增加,調用成功則將其重置為零。

    class CircuitBreaker...

    def record_failure

    @failure_count += 1

    @monitor.alert(:open_circuit) if :open == state

    end

    def reset

    @failure_count = 0

    @monitor.alert :reset_circuit

    end

    將故障失敗數與閾值進行比較,確定斷路器的狀態

    class CircuitBreaker...

    def state

    (@failure_count >= @failure_threshold) ? :open : :closed

    end


  • <noscript id="yywya"><kbd id="yywya"></kbd></noscript>
  • 东京热 下载