博客 / 詳情

返回

什麼是程序設計裏的 backoff pattern

Backoff pattern 是一種程序設計模式,通常用於處理因高負載或故障而導致的請求失敗或錯誤。該模式基於一種簡單的策略,即當請求失敗時,等待一段時間後重試,等待時間逐漸增加,直到成功或達到最大重試次數為止。

在實際應用中,Backoff pattern 通常會包含以下幾個要素:

初始等待時間:在第一次重試之前等待的時間,通常是一個較短的固定時間。

等待時間遞增因子:每次重試時等待時間的增加因子,通常是一個固定的倍數或增量。

最大等待時間:達到該等待時間後不再進行重試,防止過度等待或死循環。

最大重試次數:達到該重試次數後停止重試,防止無限重試或死循環。

Backoff pattern 的優點是能夠在高負載或故障情況下有效地處理請求失敗,並減輕服務器負載。然而,該模式也存在一些缺點,例如可能會導致響應時間變慢,因為每次失敗都需要等待一段時間後才會重試,並且需要在客户端上實現複雜的邏輯來處理重試。

一個簡單的實現 Backoff pattern 的例子可以是以下的偽代碼:

def make_request():
    retries = 0
    while retries < MAX_RETRIES:
        try:
            response = send_request()
            return response
        except Exception as e:
            if retries == MAX_RETRIES - 1:
                raise e
            retries += 1
            wait_time = INITIAL_WAIT_TIME * (BACKOFF_FACTOR ** retries)
            wait_time = min(wait_time, MAX_WAIT_TIME)
            time.sleep(wait_time)

Spartacus 裏的 backoff 機制的一個例子:

下面是一個使用 Angular HttpClient 實現 backoff pattern 的 TypeScript 代碼示例:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retryWhen, delay, take, mergeMap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  constructor(private http: HttpClient) { }

  getData(url: string): Observable<any> {
    return this.http.get(url).pipe(
      retryWhen(errors => errors.pipe(
        // 每秒重試一次,最多重試 3 次
        delay(1000),
        take(3),
        // 如果是 500 錯誤,則進行重試
        mergeMap(response => {
          if (response.status === 500) {
            return throwError(response);
          }
          return response;
        })
      ))
    );
  }
}

在這個示例中,我們定義了一個名為 DataService 的服務,該服務使用 Angular HttpClient 來獲取數據。我們使用 retryWhen 操作符來實現 backoff pattern,它將在發生錯誤時重試 HTTP 請求。

在 retryWhen 中,我們使用 delay 操作符來指定每次重試之間的延遲時間,這裏設置為 1000 毫秒。我們還使用 take 操作符來指定最大重試次數,這裏設置為 3 次。

在 mergeMap 操作符中,我們檢查響應的狀態碼是否為 500。如果是,我們使用 throwError 操作符將錯誤拋出,觸發 retryWhen 中的重試邏輯。如果響應狀態碼不是 500,則直接返回響應。

因此,這個示例中的 backoff pattern 實現了在 HTTP 請求失敗時進行重試,最多重試 3 次,每次重試之間延遲 1 秒。

user avatar jello_5c89ccf558dcc 頭像
1 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.