成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

云計算模型- 斷路器模式

KoreyLee / 1069人閱讀

摘要:斷路器模式也使系統(tǒng)能夠檢測出錯誤是否已被修復(fù)。斷路器模式的目的和重試模式有所不同。斷路器模式為在從錯誤中恢復(fù)的系統(tǒng)提供穩(wěn)定性,同時降低對性能的影響。

斷路器模式

當連接到遠程服務(wù)或資源到時候,處理那些需要一段時間才能修復(fù)的系統(tǒng)缺陷。這能優(yōu)化應(yīng)用對穩(wěn)定性和可靠性。

上下文和問題

在分布式環(huán)境中,對遠端服務(wù)或資源的請求可能會由于諸如以下臨時性錯誤而失?。壕徛木W(wǎng)絡(luò)請求,連接超時,資源被過度使用,或服務(wù)臨時不可用。通常情況下,這些錯誤能夠在短暫的中斷后自我修復(fù)。一個健壯的云端應(yīng)用應(yīng)該能夠通過重試模式等策略來處理這些問題。

然而,有的時候這些錯誤緣于一些未知的事件,從而需要更長的時間修復(fù)。這些錯誤可能是系統(tǒng)一部分無法連接,或是整個服務(wù)都響應(yīng)失敗。在這些情況下,盲目的去重試之前的操作可能并沒有意義,而且也不太可能會成功,取而代之系統(tǒng)應(yīng)該快速識別出操作失敗然后去處理這些失敗。

另外,如果一個服務(wù)非常繁忙,系統(tǒng)中的一部分出錯將導(dǎo)致級連的錯誤。例如,一個調(diào)用其他服務(wù)的操作可以設(shè)定一個超時,然后在超時后返回錯誤。然而,這個策略可能導(dǎo)致很多訪問這個服務(wù)的并發(fā)請求阻塞,直到超時。這些阻塞的請求可能占用了重要的系統(tǒng)資源,諸如內(nèi)存,線程,數(shù)據(jù)庫鏈接等。因此可能導(dǎo)致這些資源被耗盡,進而導(dǎo)致其他不相干的模塊因為資源競爭而失敗。在這些情況下,直接讓這些操作失敗,然后在合適的時候再去嘗試調(diào)用這些服務(wù),似乎是更合理的選擇。設(shè)定一個短一些的超時時長可能會有助于解決這個問題,但是又不能設(shè)定的太短而中斷那些最終可能成功的請求。

解決方案

由 Michael Nygard 在其[書中](https://pragprog.com/book/mne...)普及的斷路器模式,能夠阻止應(yīng)用重復(fù)的嘗試執(zhí)行可能失敗的請求。這允許系統(tǒng)繼續(xù)運行,而不用等待那些錯誤被修復(fù),也不用浪費 CPU 循環(huán),因為它已經(jīng)識別到該錯誤是持續(xù)性的。斷路器模式也使系統(tǒng)能夠檢測出錯誤是否已被修復(fù)。如果問題已經(jīng)被修復(fù),系統(tǒng)能夠重新調(diào)用該操作。

斷路器模式的目的和重試模式有所不同。重試模式使應(yīng)用能夠重試期望成功的操作。斷路器模式阻止應(yīng)用去調(diào)用很可能失敗的操作。應(yīng)用可以聯(lián)合使用兩種模式。然而,重試邏輯應(yīng)該能夠處理斷路器模式拋出的異常,并在斷路器指示該錯誤非短期可修復(fù)的錯誤時,停止重試。

斷路器為可能會失敗的操作充當代理的角色。這個代理監(jiān)視最近發(fā)生的失敗的數(shù)量,然后用這些信息判斷是否繼續(xù)執(zhí)行該操作,還是直接返回異常。

該代理可以通過一個狀態(tài)機來實現(xiàn),該狀態(tài)機應(yīng)模擬電子斷路器來實現(xiàn)以下狀態(tài):

關(guān)閉:來自應(yīng)用的請求直接路由到對應(yīng)的操作。代理維護一個計數(shù)器來記錄最近失敗的次數(shù)。如果一個操作失敗,該計數(shù)器加一。如果最近失敗的次數(shù)在指定時間段內(nèi)超過一個閾值,代理被設(shè)定到 開啟 狀態(tài)。同時,代理啟動一個計時器,當計時器超時后,代理被設(shè)定到 半開狀態(tài)。

設(shè)定計時器的目的是在應(yīng)用重試該操作前,給系統(tǒng)留出時間修復(fù)導(dǎo)致該錯誤的問題。

開啟:從應(yīng)用發(fā)送給該服務(wù)的請求直接失敗,并返回異常。

半開:允許少量的請求通過代理調(diào)用該操作。如果請求成功,系統(tǒng)假定之前引起操作失敗的錯誤已被修復(fù),斷路器設(shè)定到 關(guān)閉狀態(tài)(且將失敗計數(shù)器重置)。如果任何請求失敗,斷路器便假定之前的錯誤依舊存在,然后把狀態(tài)重新置為打開,重啟超時計時器,并為系統(tǒng)恢復(fù)該錯誤設(shè)定更長的恢復(fù)時間。

半開 狀態(tài)有助于使恢復(fù)中的系統(tǒng)避免遭受突發(fā)的大量請求。在服務(wù)恢復(fù)過程中,它可能只能支撐有限數(shù)量的請求,直至恢復(fù)完全完成。在恢復(fù)過程中接收大量請求,可能會使服務(wù)超時,甚至再次失敗。

在上圖中,關(guān)閉狀態(tài)下使用的計數(shù)器是基于時間的,它會自動定期重置。這能夠使斷路器避免因偶發(fā)性失敗而切換到失敗狀態(tài)。失敗閾值設(shè)定使斷路器只有在指定的時間內(nèi)失敗的次數(shù)達到了指定值后才切換到失敗狀態(tài)。半開狀態(tài)下使用的計數(shù)器用來記錄請求成功的次數(shù)。當連續(xù)成功的請求數(shù)量超過一個指定值后,斷路器將切換到 關(guān)閉狀態(tài)。如果任一調(diào)用失敗,斷路器將直接進入打開狀態(tài),下次進入半開狀態(tài)的時候,成功計數(shù)器將被清零。

系統(tǒng)如何修復(fù)是屬于本模式以外的內(nèi)容,可能通過重新加載數(shù)據(jù),重啟失敗的組件,或是修復(fù)網(wǎng)絡(luò)問題。

斷路器模式為在從錯誤中恢復(fù)的系統(tǒng)提供穩(wěn)定性,同時降低對性能的影響。它通過快速駁回可能失敗的請求來降低系統(tǒng)響應(yīng)時間。如果每次斷路器切換狀態(tài)時都觸發(fā)一個時間,則可以用來監(jiān)視斷路器保護部分的系統(tǒng)狀態(tài),或在斷路器切換到 打開狀態(tài)時為管理員提供報警。

這個模式是可定制的,而且可適配不同類型的錯誤。例如,你可以將超時計數(shù)器的值調(diào)高,你可以將斷路器處在狀態(tài)的初始值設(shè)為幾秒,然后如果到時后失敗未解決將超時器設(shè)為幾分鐘等。在一些情況下,除了讓處在狀態(tài)的斷路器返回失敗和異常,也可以將其配置為返回一個對應(yīng)用有意義的默認值。

問題和注意事項

當考慮如何實現(xiàn)該模式時,需要考慮如下問題:

異常處理。應(yīng)用通過斷路器調(diào)用服務(wù)需準備好如何處理因服務(wù)無法訪問而產(chǎn)生的異常。處理異常的方式因應(yīng)用不同而不同。例如,應(yīng)用應(yīng)能臨時降級它對應(yīng)的功能,調(diào)用候選的能獲得同樣數(shù)據(jù)的應(yīng)用,或向用戶報告錯誤,請其過后重試。

異常的類型。請求可能由于各種原因而失敗,其中一些導(dǎo)致的問題可能比其他更嚴重。例如,請求可能由于外部服務(wù)宕機而失敗從而中斷數(shù)分鐘,或者由于服務(wù)過載而導(dǎo)致超時。斷路器可能能夠檢測異常的類型從而使用不同的策略。例如,如果要把斷路器設(shè)定到 狀態(tài),超時類型到錯誤次數(shù)的閾值要比系統(tǒng)完全不可用的閾值要高很懂。

日志。斷路器應(yīng)該記錄所有失敗的請求(如何可以,也可以記錄成功的)來允許管理員來監(jiān)控操作的健康狀況。

可恢復(fù)性。你應(yīng)該為斷路器配置其保護的操作可能的恢復(fù)模型。例如,如果斷路器在打開狀態(tài)維持了很長時間,可能導(dǎo)致即使錯誤已經(jīng)修復(fù),斷路器仍拋出異常。類似的,如果斷路器從半開的時間太短,可能導(dǎo)致它上下波動,減少應(yīng)用的響應(yīng)時間(??沒懂)。

測試失敗的操作。在的狀態(tài)下,除了用計數(shù)器來決定何時切換到半開狀態(tài),斷路器還可以啟用一個定時任務(wù)來周期性 ping 遠端服務(wù)來判斷該服務(wù)是否已可以訪問??梢圆捎脟L試調(diào)用之前失敗的服務(wù)的形式,或調(diào)用遠端服務(wù)提供的專門用來測試服務(wù)狀態(tài)的操作,如健康狀況健康模式 所描述的那樣。

手動重載。對于系統(tǒng)恢復(fù)時間波動非常大的系統(tǒng),提供一個手動重置選項來方便管理員關(guān)閉斷路器(同時重置失敗計數(shù)器)是很有用的。類似的,如果斷路器所保護的服務(wù)臨時不可用,管理員可以強制打開斷路器將其置為狀態(tài)(同時重置計時器)。

并發(fā)。斷路器可能同時被大量客戶端訪問。其實現(xiàn)不用阻塞并發(fā)的請求,也不能給操作添加過多的額外負載。

資源區(qū)分。當我們?yōu)橐粋€由多個獨立的提供者提供的同一個資源使用斷路器時,我們需要額外注意。例如,在一個由多個分片的數(shù)據(jù)存儲資源中,即便其他分片遇到臨時錯誤,單個分片也可以接受完全的訪問。如果在這種場景中,這些錯誤被合并成同一錯誤,應(yīng)用可能會在某些分片錯誤時嘗試去訪問其他分片,但由于斷路器的存在,對其他分片的訪問也可能會被阻塞,即使它們可能成功。

加速熔斷。有時候返回的錯誤信息包含足夠信息令斷路器斷路。例如,一個共享資源過載,可直接另斷路器斷路而避免應(yīng)用馬上重試。

[!注意事項]
一個服務(wù)可能在限流時返回 HTTP 429(太多的請求),或者在服務(wù)當前不可用時返回 HTTP 503(服務(wù)不可用)。HTTP 返回信息中可能包含了額外信息,比如下次重試的間隔時間等。

重放失敗的請求。在打開的狀態(tài)下,除了直接返回失敗,斷路器也可以將每個請求的詳細信息記錄到日志中,然后然后在遠程資源可訪問后,重放該請求。
外部服務(wù)不適合的超時。斷路器不適合用來保護那些設(shè)置了過長超時時長的外部服務(wù)。如果超時時間過長,斷路器的線程可能阻塞,在這段時間內(nèi),其他應(yīng)用可能耶嘗試調(diào)用這個服務(wù),從而導(dǎo)致斷路器消耗大量的線程。

什么時候使用該模式

在以下場景可以使用該模式:

阻止應(yīng)用訪問一個很可能失敗的共享的遠程服務(wù)或資源。

以下場景不應(yīng)該用該模式:

訪問本地資源,比如內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)。在這個場景中,使用斷路器將為你的系統(tǒng)帶來額外的開銷。

用來替代業(yè)務(wù)邏輯中的異常處理。

例子

在 web 應(yīng)用中,頁面是根據(jù)外部服務(wù)獲得的數(shù)據(jù)計算生成的。如果系統(tǒng)設(shè)定較少的緩存策略,大多數(shù)頁面點擊都會調(diào)用一次服務(wù)。從 web 應(yīng)用到服務(wù)的請求可以設(shè)定超時時間(通常是60秒),如果服務(wù)在這段時間內(nèi)未響應(yīng),頁面的邏輯將認為服務(wù)不可用并拋出異常。

然而,如果服務(wù)失敗并且系統(tǒng)非常繁忙,用戶可能需要等60秒才會被提示異常。最終內(nèi)存,鏈接,線程等資源可能會用盡,阻止其他用戶連接系統(tǒng),即使它們并不是訪問失敗的那個服務(wù)。

通過添加更多的網(wǎng)絡(luò)服務(wù)器和實現(xiàn)負載均衡來為系統(tǒng)擴容能夠延緩資源耗盡的時間,但這并不會解決這個問題因為用戶的請求仍會未響應(yīng)并且最終所以網(wǎng)絡(luò)服務(wù)器的資源終會耗盡。

為訪問該服務(wù)查詢數(shù)據(jù)的連接包裹一層斷路器能夠解決該問題,并且能更優(yōu)雅地解決服務(wù)失敗。用戶的請求仍會失敗,但失敗將會更迅速并且不會阻塞資源。

The CircuitBreaker class maintains state information about a circuit breaker in an object that implements the ICircuitBreakerStateStore interface shown in the following code.

interface ICircuitBreakerStateStore
{
  CircuitBreakerStateEnum State { get; }

  Exception LastException { get; }

  DateTime LastStateChangedDateUtc { get; }

  void Trip(Exception ex);

  void Reset();

  void HalfOpen();

  bool IsClosed { get; }
}

The State property indicates the current state of the circuit breaker, and will be either Open, HalfOpen, or Closed as defined by the CircuitBreakerStateEnum enumeration. The IsClosed property should be true if the circuit breaker is closed, but false if it"s open or half open. The Trip method switches the state of the circuit breaker to the open state and records the exception that caused the change in state, together with the date and time that the exception occurred. The LastException and the LastStateChangedDateUtc properties return this information. The Reset method closes the circuit breaker, and the HalfOpen method sets the circuit breaker to half open.

The InMemoryCircuitBreakerStateStore class in the example contains an implementation of the ICircuitBreakerStateStore interface. The CircuitBreaker class creates an instance of this class to hold the state of the circuit breaker.

The ExecuteAction method in the CircuitBreaker class wraps an operation, specified as an Action delegate. If the circuit breaker is closed, ExecuteAction invokes the Action delegate. If the operation fails, an exception handler calls TrackException, which sets the circuit breaker state to open. The following code example highlights this flow.

public class CircuitBreaker
{
  private readonly ICircuitBreakerStateStore stateStore =
    CircuitBreakerStateStoreFactory.GetCircuitBreakerStateStore();

  private readonly object halfOpenSyncObject = new object ();
  ...
  public bool IsClosed { get { return stateStore.IsClosed; } }

  public bool IsOpen { get { return !IsClosed; } }

  public void ExecuteAction(Action action)
  {
    ...
    if (IsOpen)
    {
      // The circuit breaker is Open.
      ... (see code sample below for details)
    }

    // The circuit breaker is Closed, execute the action.
    try
    {
      action();
    }
    catch (Exception ex)
    {
      // If an exception still occurs here, simply
      // retrip the breaker immediately.
      this.TrackException(ex);

      // Throw the exception so that the caller can tell
      // the type of exception that was thrown.
      throw;
    }
  }

  private void TrackException(Exception ex)
  {
    // For simplicity in this example, open the circuit breaker on the first exception.
    // In reality this would be more complex. A certain type of exception, such as one
    // that indicates a service is offline, might trip the circuit breaker immediately.
    // Alternatively it might count exceptions locally or across multiple instances and
    // use this value over time, or the exception/success ratio based on the exception
    // types, to open the circuit breaker.
    this.stateStore.Trip(ex);
  }
}

The following example shows the code (omitted from the previous example) that is executed if the circuit breaker isn"t closed. It first checks if the circuit breaker has been open for a period longer than the time specified by the local OpenToHalfOpenWaitTime field in the CircuitBreaker class. If this is the case, the ExecuteAction method sets the circuit breaker to half open, then tries to perform the operation specified by the Action delegate.

If the operation is successful, the circuit breaker is reset to the closed state. If the operation fails, it is tripped back to the open state and the time the exception occurred is updated so that the circuit breaker will wait for a further period before trying to perform the operation again.

If the circuit breaker has only been open for a short time, less than the OpenToHalfOpenWaitTime value, the ExecuteAction method simply throws a CircuitBreakerOpenException exception and returns the error that caused the circuit breaker to transition to the open state.

Additionally, it uses a lock to prevent the circuit breaker from trying to perform concurrent calls to the operation while it"s half open. A concurrent attempt to invoke the operation will be handled as if the circuit breaker was open, and it"ll fail with an exception as described later.

    ...
    if (IsOpen)
    {
      // The circuit breaker is Open. Check if the Open timeout has expired.
      // If it has, set the state to HalfOpen. Another approach might be to
      // check for the HalfOpen state that had be set by some other operation.
      if (stateStore.LastStateChangedDateUtc + OpenToHalfOpenWaitTime < DateTime.UtcNow)
      {
        // The Open timeout has expired. Allow one operation to execute. Note that, in
        // this example, the circuit breaker is set to HalfOpen after being
        // in the Open state for some period of time. An alternative would be to set
        // this using some other approach such as a timer, test method, manually, and
        // so on, and check the state here to determine how to handle execution
        // of the action.
        // Limit the number of threads to be executed when the breaker is HalfOpen.
        // An alternative would be to use a more complex approach to determine which
        // threads or how many are allowed to execute, or to execute a simple test
        // method instead.
        bool lockTaken = false;
        try
        {
          Monitor.TryEnter(halfOpenSyncObject, ref lockTaken);
          if (lockTaken)
          {
            // Set the circuit breaker state to HalfOpen.
            stateStore.HalfOpen();

            // Attempt the operation.
            action();

            // If this action succeeds, reset the state and allow other operations.
            // In reality, instead of immediately returning to the Closed state, a counter
            // here would record the number of successful operations and return the
            // circuit breaker to the Closed state only after a specified number succeed.
            this.stateStore.Reset();
            return;
          }
          catch (Exception ex)
          {
            // If there"s still an exception, trip the breaker again immediately.
            this.stateStore.Trip(ex);

            // Throw the exception so that the caller knows which exception occurred.
            throw;
          }
          finally
          {
            if (lockTaken)
            {
              Monitor.Exit(halfOpenSyncObject);
            }
          }
        }
      }
      // The Open timeout hasn"t yet expired. Throw a CircuitBreakerOpen exception to
      // inform the caller that the call was not actually attempted,
      // and return the most recent exception received.
      throw new CircuitBreakerOpenException(stateStore.LastException);
    }
    ...

To use a CircuitBreaker object to protect an operation, an application creates an instance of the CircuitBreaker class and invokes the ExecuteAction method, specifying the operation to be performed as the parameter. The application should be prepared to catch the CircuitBreakerOpenException exception if the operation fails because the circuit breaker is open. The following code shows an example:

var breaker = new CircuitBreaker();

try
{
  breaker.ExecuteAction(() =>
  {
    // Operation protected by the circuit breaker.
    ...
  });
}
catch (CircuitBreakerOpenException ex)
{
  // Perform some different action when the breaker is open.
  // Last exception details are in the inner exception.
  ...
}
catch (Exception ex)
{
  ...
}
相關(guān)模式與指導(dǎo)

在實現(xiàn)該模式時,以下模式也會有幫助:

重試模式。

當應(yīng)用嘗試連接服務(wù)或網(wǎng)絡(luò)資源時遇到臨時性錯誤時,簡單的重試之前失敗的操作。

健康狀態(tài)監(jiān)控模式。

斷路器應(yīng)該能夠通過給服務(wù)端點發(fā)送請求來測試服務(wù)的健康狀況。服務(wù)應(yīng)該能夠返回信息來表明自身狀況。

翻譯自 Azure Cloud Design Patterns

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25245.html

相關(guān)文章

  • 計算模型 - 1. 概述

    摘要:讀了微軟總結(jié)的云計算設(shè)計模式系列文章,覺得很受啟發(fā),遂將這個系列翻譯出來如下。每個模式都描述了該模式試圖解決的問題,在使用該模式時應(yīng)考慮的問題,以及一個基于微軟云的例子。 讀了微軟 Azure 總結(jié)的云計算設(shè)計模式系列文章,覺得很受啟發(fā),遂將這個系列翻譯出來如下。 云計算模型 這些設(shè)計模式對于在云上構(gòu)建高可用性,伸縮性,安全的應(yīng)用程序很有用。每個模式都描述了該模式試圖解決的問題,在使用...

    MarvinZhang 評論0 收藏0
  • 計算模型 - 1. 概述

    摘要:讀了微軟總結(jié)的云計算設(shè)計模式系列文章,覺得很受啟發(fā),遂將這個系列翻譯出來如下。每個模式都描述了該模式試圖解決的問題,在使用該模式時應(yīng)考慮的問題,以及一個基于微軟云的例子。 讀了微軟 Azure 總結(jié)的云計算設(shè)計模式系列文章,覺得很受啟發(fā),遂將這個系列翻譯出來如下。 云計算模型 這些設(shè)計模式對于在云上構(gòu)建高可用性,伸縮性,安全的應(yīng)用程序很有用。每個模式都描述了該模式試圖解決的問題,在使用...

    ruicbAndroid 評論0 收藏0
  • 部署微服務(wù):Spring Cloud vs. Kubernetes

    摘要:而微服務(wù)架構(gòu)能否成功實踐,利用各種工具解決潛在問題是關(guān)鍵。因此,微服務(wù)本身可以通過庫和運行時代理解決客戶端服務(wù)發(fā)現(xiàn)負載均衡配置更新統(tǒng)計跟蹤等。與相比,解決了更廣的微服務(wù)架構(gòu)問題。和處理了不同范圍的微服務(wù)架構(gòu)技術(shù)點,而且是用了不同的方法。 Spring Cloud vs. Kubernetes,誰才是部署微服務(wù)的最佳拍檔? Spring Cloud和Kubernetes都聲稱自己是開發(fā)和...

    YanceyOfficial 評論0 收藏0
  • 2021 年最新基于 Spring Cloud 的微服務(wù)架構(gòu)分析

    摘要:是一個相對比較新的微服務(wù)框架,年才推出的版本雖然時間最短但是相比等框架提供的全套的分布式系統(tǒng)解決方案。提供線程池不同的服務(wù)走不同的線程池,實現(xiàn)了不同服務(wù)調(diào)用的隔離,避免了服務(wù)器雪崩的問題。通過互相注冊的方式來進行消息同步和保證高可用。 Spring Cloud 是一個相對比較新的微服務(wù)框架,...

    cikenerd 評論0 收藏0
  • 2012年6月14日Amazon服務(wù)故障分析

    摘要:日,公布了事故分析。此外,亞馬遜還完成了對所有備用配電的審計。至此,亞馬遜表示,已經(jīng)確定所有斷路器都是正確的配置了,并會進行定期的測試和審計。最后,亞馬遜對在這次事件中受到損失的企業(yè)表示了歉意。 上周四即6月14日,Amazon位于美國東部的數(shù)據(jù)中心出現(xiàn)故障,并影響了AWS多項云服務(wù)以及基于之上的Heroku、Quora等知名網(wǎng)站。16日,Amaozn公布了事故分析。事故是由公共電網(wǎng)故障引...

    Luosunce 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<