Boto3のコネクションタイムアウト値について教えてください
この記事はアノテーション株式会社 AWS Technical Support Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 8日目の記事です。
困っていた内容
AWS SDK for Python (Boto3)におけるリトライ処理の動作を確認するため、EC2上のPythonスクリプトで、Boto3のタイムアウトの処理をテストしました。
- connect_timeoutのtimeout値を5秒
- max_attemptsを3回
- retrymodeをstandard
上記の設定をして SecretsManager にアクセスしました。
この設定だと、20秒ほどでタイムアウトする想定になりますが、 実際に試してみると、65秒経過後にタイムアウトが発生しました。 想定とのギャップが発生する理由を教えてください。
(セキュリティグループのアクセス許可を外した状態でテストを実施しました)
import boto3 from botocore.config import Config config = Config( connect_timeout=5, retries={ 'max_attempts': 3, 'mode': 'standard' }) client = boto3.client( service_name='secretsmanager', region_name='ap-northeast-1', config=config )
どう対応すればいいの?
東京リージョンで、SecretsManagerのエンドポイントのIPアドレスを確認すると、3件登録されていました。
dig secretsmanager.ap-northeast-1.amazonaws.com ... secretsmanager.ap-northeast-1.amazonaws.com. 41 IN A 54.249.xx.xx secretsmanager.ap-northeast-1.amazonaws.com. 41 IN A 54.168.xx.xx secretsmanager.ap-northeast-1.amazonaws.com. 41 IN A 54.238.xx.xx
※ なお、DNSに登録されているエンドポイントのIPアドレスの数は、サービスにより異なるようです。
この状態で上記のテストを行った場合、1 attempt毎に3回の接続試行をしているので、
5 ✕ 3 = 15
15秒ほどかかります。
一方で、DNSを参照しない形で、 /etc/hosts でSecretsManagerのエンドポイントのIPアドレスを、1件だけ指定した場合は、 1 attempt毎に1回の接続試行をします。
パラメータとして
connect_timeout:5
max_attempts:3
を指定した場合、それぞれ下記のような動作になります。
DNSから3件のIPアドレスが返される場合:
attempt1 17:00:00 (5×3=15秒) attempt2 17:00:15 (5×3=15秒) attempt3 17:00:30 (5×3=15秒) attempt4 17:00:45 (5×3=15秒) → 約60秒後にエラーで終了
hostsファイルで1件だけIPアドレスを指定した場合:
attempt1 17:00:00 (5×1=5秒) attempt2 17:00:05 (5×1=5秒) attempt3 17:00:10 (5×1=5秒) attempt4 17:00:15 (5×1=5秒) → 約20秒後にエラーで終了
※ 実際には、エクスポネンシャルバックオフ・アルゴリズムによるジッター(ランダムな遅延時間)が数秒ほど加算されます。
参考資料
[1] Config Reference — botocore 1.23.21 documentation
[2] AWS SDK for Python (Boto3)の エラーの再試行について