📦 AWS SQS DLQ & Redrive Policy

Dead Letter Queue(不達荷物センター)とRedrive Policy(再配達ルール)を宅配便システムで完全理解!

🏢 宅配便配送センターのシナリオ

AWS SQS = 宅配便の配送システム

🏪 AWS配送センター株式会社

📋 システム構成

  • 🎯 SQS Queue = 配送待ち荷物置き場
  • 📦 Message = お客様への荷物
  • 🚚 Consumer = 配達員ドライバー
  • 🏪 DLQ = 不達荷物保管センター

⚠️ 配達問題の例

  • 🏠 住所不明 - 引っ越し済み
  • 😴 不在 - 受取人がいない
  • 🚫 受け取り拒否 - 注文キャンセル
  • 🔧 システムエラー - 配達員の機械故障

🌊 荷物の流れ - メインキューからDLQまで

配送失敗時の荷物がどのように移動するかを見てみよう!

25
📮
メインキュー
配送待ちの荷物
(SQS Main Queue)
通常の配達リスト
➡️
配達試行
3
🚫
Dead Letter Queue
配達不可能な荷物
(DLQ)
再配達限界に到達

🚚 配達プロセスの詳細

📦
荷物
取得
メインキューから荷物を取得
➡️
🚚
配達
試行
お客様の住所に配達を試行
➡️

結果
確認
配達成功 or 失敗を判定
➡️
🔄
再配達
判定
再配達回数をチェック

📦 Step 1: 荷物取得

配達員がメインキューから荷物を受け取ります。この時点で荷物は「配達中」状態になり、他の配達員からは見えなくなります。

  • AWS用語: Consumer が SQS Message を Receive
  • Visibility Timeout: 配達員が荷物を独占する時間
  • 状態変化: Available → In-Flight
📮
メインキュー
📦
🏠
配達先

🔄 Redrive Policy - 再配達ルール

何回まで再配達を試みるかのルール設定

再配達カウンター

現在の試行回数
2
/
最大再配達回数
3

📋 再配達ルール(maxReceiveCount)

✅ 再配達可能
まだ最大回数に達していない
🚫 DLQに移動
最大回数に達した場合

🔧 AWS 設定例

# maxReceiveCount = 3
{
  "deadLetterTargetArn": "arn:aws:sqs:us-east-1:123456789012:my-dlq",
  "maxReceiveCount": 3
}
意味: 3回配達失敗したらDLQに送る

💡 推奨設定値

  • 一般的: maxReceiveCount = 3~5
  • クリティカル: maxReceiveCount = 1~2
  • バッチ処理: maxReceiveCount = 5~10

🎮 配達シミュレーター

実際に配達を試して、DLQ移動プロセスを体験しよう!

配達結果を選択してシミュレーション

📊 配送センター リアルタイム状況

📮
100
メインキュー
配達待ち荷物
🔄
0
現在の再配達回数
(maxReceiveCount: 3)
🚫
5
DLQ
配達不可荷物
892
配達完了
成功した荷物
🎯 シミュレーション待機中 - 上のボタンを押して配達を開始してください

⚙️ AWS SQS DLQ設定の実装

実際のAWS環境での設定方法とコード例

🔧 AWS CLI 設定例

# 1. DLQの作成
aws sqs create-queue \
  --queue-name my-app-dlq \
  --attributes '{
    "MessageRetentionPeriod": "1209600"
  }'
# 2. メインキューの作成
aws sqs create-queue \
  --queue-name my-app-queue \
  --attributes '{
    "RedrivePolicy": "{
      \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-1:123456789012:my-app-dlq\",
      \"maxReceiveCount\": 3
    }",
    "VisibilityTimeoutSeconds": "30"
  }'

📝 CloudFormation テンプレート

Resources:
  MyAppDLQ:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: my-app-dlq
      MessageRetentionPeriod: 1209600
      
  MyAppQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: my-app-queue
      VisibilityTimeoutSeconds: 30
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt MyAppDLQ.Arn
        maxReceiveCount: 3
      
  # アラーム設定
  DLQAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: DLQ-Messages-Alert
      MetricName: ApproximateNumberOfMessages
      Namespace: AWS/SQS
      Statistic: Sum
      Period: 300
      EvaluationPeriods: 1
      Threshold: 1
      ComparisonOperator: GreaterThanOrEqualToThreshold
      Dimensions:
        - Name: QueueName
          Value: !GetAtt MyAppDLQ.QueueName

💻 アプリケーションコード例(Python)

import boto3
import json
from botocore.exceptions import ClientError

class SQSDeliveryService:
    def __init__(self):
        self.sqs = boto3.client('sqs')
        self.queue_url = 'https://sqs.us-east-1.amazonaws.com/123456789012/my-app-queue'
        self.dlq_url = 'https://sqs.us-east-1.amazonaws.com/123456789012/my-app-dlq'
    
    def process_messages(self):
        """メッセージ処理(配達員の仕事)"""
        try:
            # メッセージ受信(荷物取得)
            response = self.sqs.receive_message(
                QueueUrl=self.queue_url,
                MaxNumberOfMessages=1,
                WaitTimeSeconds=20,
                MessageAttributeNames=['All']
            )
            
            if 'Messages' in response:
                message = response['Messages'][0]
                receipt_handle = message['ReceiptHandle']
                
                # 配達処理を実行
                delivery_success = self.deliver_package(message)
                
                if delivery_success:
                    # 配達成功 → メッセージ削除
                    self.sqs.delete_message(
                        QueueUrl=self.queue_url,
                        ReceiptHandle=receipt_handle
                    )
                    print("✅ 配達成功!メッセージを削除しました")
                else:
                    # 配達失敗 → SQSが自動的にreceiveCountを増加
                    # maxReceiveCountに達するとDLQに自動移動
                    print("❌ 配達失敗。再配達キューに戻ります")
                    
        except ClientError as e:
            print(f"🚨 エラー: {e}")
    
    def deliver_package(self, message):
        """実際の配達処理(ビジネスロジック)"""
        try:
            # ここで実際の配達処理を実行
            # 例:APIコール、データベース更新、外部サービス連携等
            package_data = json.loads(message['Body'])
            
            # 配達シミュレーション
            if self.simulate_delivery(package_data):
                return True
            else:
                return False
                
        except Exception as e:
            print(f"配達中にエラー: {e}")
            return False
    
    def monitor_dlq(self):
        """DLQ監視(不達荷物のチェック)"""
        response = self.sqs.get_queue_attributes(
            QueueUrl=self.dlq_url,
            AttributeNames=['ApproximateNumberOfMessages']
        )
        
        message_count = int(response['Attributes']['ApproximateNumberOfMessages'])
        
        if message_count > 0:
            print(f"⚠️ DLQに{message_count}個の不達荷物があります")
            # アラート送信やログ出力などの処理
            
    def simulate_delivery(self, package_data):
        """配達成功/失敗のシミュレーション"""
        import random
        # 80%の確率で配達成功
        return random.random() < 0.8

# 使用例
if __name__ == "__main__":
    service = SQSDeliveryService()
    
    # メッセージ処理開始
    while True:
        service.process_messages()
        service.monitor_dlq()
        time.sleep(5)

📊 設定パラメータ比較とベストプラクティス

適切な設定値とその影響を理解しよう

maxReceiveCount 設定値による影響比較
設定値
メリット
デメリット
1-2回
(厳格)
✅ 即座に問題検出
✅ システム負荷軽減
✅ 障害の早期発見
❌ 一時的問題で失敗
❌ DLQ増加の可能性
❌ 偽陽性リスク
3-5回
(標準)
✅ バランス良好
✅ 一時的問題に対応
✅ 実用的な設定
⚠️ 中程度の遅延
⚠️ リソース使用
6回以上
(寛容)
✅ 確実な再試行
✅ ネットワーク問題に対応
✅ データ損失回避
❌ 処理遅延
❌ リソース無駄
❌ 問題検出遅延

🏆 DLQ運用のベストプラクティス

📊
監視とアラート
DLQにメッセージが蓄積されたら即座にアラート。CloudWatchでメトリクス監視を設定し、DLQ内のメッセージ数を定期チェック。
🔄
Redrive機能活用
問題修正後、DLQからメインキューへのRedriveを実行。AWSコンソールまたはAPIで簡単に実行可能。
📝
DLQメッセージ分析
DLQのメッセージを定期分析して根本原因を特定。エラーパターンの把握により、システム改善に活用。
適切な保持期間
DLQのメッセージ保持期間を14日(最大)に設定。十分な調査時間を確保しつつ、コスト最適化を図る。
🔐
セキュリティ設定
DLQにも適切なIAMポリシーを設定。機密情報を含むメッセージの場合は、暗号化設定も必須。
📈
段階的対応
DLQメッセージの対応は段階的に実施。まず少数をテスト的にRedriveし、成功を確認してから全量対応。

Created by SSuzuki1063

AWS SAP Learning Resources

Created by SSuzuki1063

AWS SAP Learning Resources