はじめに
ネットワークの処理でエラーが発生した際のリトライ処理(Exponential backoff)について勉強したので備忘録も兼ねて本記事を作成しています。
Exponential backoffとは?
指数関数的にリトライする間隔を後退させる(遅らせる)アルゴリズムです。
エラーが発生した際に次のリトライ処理を1秒後、2秒後、4秒後、8秒後というようにリトライの間隔を指数関数的に長くしていく手法です。
これだけだとリトライ間隔も同じになってしまうため、ランダム値のジッターを使用しリトライの時間を分散させる。
環境
python 3.12
ソース
一定の確率で処理を失敗させリトライ間隔を遅らせながら、再試行回数が最大値に達するまで試行を続けます。
lambda_function.py
import time
import random
# 再試行に関する設定
MAX_RETRIES = 5
BASE_DELAY = 1
def simulate_operation():
# 70%の確率で失敗させる
if random.random() < 0.7:
raise Exception("失敗")
return "成功"
def lambda_handler(event, context):
# 現在の再試行回数を取得
retries = event.get('retries', 0)
# 待機時間を計算
delay = (2 ** retries) * BASE_DELAY + random.random()
# 最大再試行回数を超えた場合
if retries > MAX_RETRIES:
return {
'statusCode': 500,
'body': '最大再試行回数を超えました'
}
try:
# 失敗をシミュレート
result = simulate_operation()
print('成功')
return {
'statusCode': 200,
'body': result
}
except Exception as e:
print(f"試行回数: {retries + 1} 失敗: {str(e)}")
# スリープ
time.sleep(delay)
# 更新された再試行回数を持つイベントを準備して再帰的に呼び出す
updated_event = {
'retries': retries + 1
}
return lambda_handler(updated_event, context)
実行結果
Lambdaをテスト実行しCWからログを確認すると1回目、2回目のリトライ処理では失敗していますが、3回目のリトライで成功している事が確認できます。
タイムスタンプ メッセージ
2024-~~ 試行回数: 0 , 失敗
2024-~~ 試行回数: 1 , 失敗
2024-~~ 試行回数: 2 , 失敗
2024-~~ 成功
参考