aws SQSのDead Letter Queueを触ってみる

多くのメッセージングシステムでは、正常に処理されなかったメッセージは Dead Letter Queue(DLQ) に溜め込み、異常系メッセージを別途処理する機能が提供されている。

What will the messaging system do with a message it cannot deliver?

Amazon のメッセージングシステム SQS2014/01 から DLQ に対応したようなので

から触ってみた。

AWS SQS の Dead Letter Queue について

SQS ではメッセージを受け取ったあと

  • 明示的にメッセージ削除するとキューから削除される
  • Default Visibility Timeout を超えても削除されなかったメッセージは再びエンキューされる

また、キューイング後、Message Retention Period を超えるとキューから削除される。
そのため、自前で異常系メッセージを消し込む処理を入れない限り、延々と同じ異常メッセージを処理しなければいけなかった。

SQS の Dead Letter Queue 機能を使うと、キューごに maxReceiveCount を設定することで、累計の受け取り回数が maxReceiveCount を超えたメッセージは、指定した Dead Letter Queue に自動的にエンキューされるようになる。

詳細手順は、オフィシャルのドキュメントを参照。

AWS Documentation >> Amazon Simple Queue Service >> Developer Guide >> Using Amazon SQS Dead Letter Queues

AWS CLI から触ってみる

テストシナリオ

以下のようなシナリオをやる

  1. dead letter queue “test_dlq” を作成
  2. 通常のキュー “test_q” を作成
  3. test_q に dead letter queue 設定を行う(maxReceiveCount は3)
  4. メッセージを受け取ったあと、”Default Visibility Timeout” が来るまで放置し、エンキューさせる
  5. この操作を繰り返す
  6. 受け取り回数が maxReceiveCount を超えると、test_q からメッセージが消え、dead letter queue “test_dlq” にエンキューされる

キューの作成

$ aws sqs create-queue --queue-name test_q --attributes VisibilityTimeout=15,MessageRetentionPeriod=300
{
    "QueueUrl": "https://queue.amazonaws.com/423000/test_q"
}
$ aws sqs create-queue --queue-name test_dlq --attributes VisibilityTimeout=15,MessageRetentionPeriod=300
{
    "QueueUrl": "https://ap-northeast-1.queue.amazonaws.com/423000/test_dlq
}

DLQ の設定

CLI から DLQ の設定をする

$ aws sqs set-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_q \
  --attributes '{"RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:ap-northeast-1:423000:test_dlq\",\"maxReceiveCount\":3}"}'

CLI から DLQ 設定を確認

# DLQ へのルーティングポリシー
$ aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names RedrivePolicy
{
    "Attributes": {
        "RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:ap-northeast-1:423000:test_dlq\",\"maxReceiveCount\":3}"
    }
}
# DLQ test_dlq にルーティングしているキュー一覧
$ aws  sqs list-dead-letter-source-queues --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_dlq
{
    "queueUrls": [
        "https://queue.amazonaws.com/423000/test_q"
    ]
}

正常系のメセージ処理

まずは正常系。

メッセージを送信

$ aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --message-body a
{
    "MD5OfMessageBody": "0cc175b9c0f1b6a831c399e269772661",
    "MessageId": "3cf9..."
}

メッセージを受信。放置

$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": [
        {
            "Body": "a",
            "Attributes": {
                "ApproximateReceiveCount": "1"
            },
            "ReceiptHandle": "0NNAq...",
            "MD5OfBody": "0cc175b9c0f1b6a831c399e269772661",
            "MessageId": "3cf9..."
        }
    ]
}

メッセージを再受信。受信回数が増えている

$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": [
        {
            "Body": "a",
            "Attributes": {
                "ApproximateReceiveCount": "2"
            },
            "ReceiptHandle": "0NNAq...",
            "MD5OfBody": "0cc175b9c0f1b6a831c399e269772661",
            "MessageId": "3cf9..."
        }
    ]
}

受信メッセージを削除。

$ aws sqs delete-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --receipt-handle "0NNAq..."

メッセージを受信。メッセージは削除されたので、キューは空。

$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": []
}

異常系のメセージ処理

次に DLQ にルーティングされるような異常系を確認。

メッセージを送信

$ aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --message-body b
{
    "MD5OfMessageBody": "92eb5ffee6ae2fec3ad71c777531578f",
    "MessageId": "49d82701-d6d2-4b83-b0aa-77a8033e407c"
}

メッセージを受信

# 1st receive
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": [
        {
            "Body": "b",
            "Attributes": {
                "ApproximateReceiveCount": "1"
            },
            "ReceiptHandle": "0NNAq8PwvXuRAEX6o9P6QNdJUg4Y+kIYEDd4N+5gSBkTUuBeeLWtgVhow/UbbZQdRae4IiNl633xy+txSc6DaIJnhF4nCiNrDUqgTBAvrX7SplJepZULfbiFYQ7jIIOMUaRdiZdhzI7yZX7ym273+ZVjva2+BN2oHzuqBREfrDXdK1B6uYcn01N0oUDasPCEaNA/5oCpDyBAQN0dRjdXaEJoKHjdUbilzP8I7wzSwco6XYwrLetluMlqYh24jIpp+XsEHcec/C3vJ0LaQvwf1uaE/HDVrIaotFgLo2wcVEs=",
            "MD5OfBody": "92eb5ffee6ae2fec3ad71c777531578f",
            "MessageId": "49d82701-d6d2-4b83-b0aa-77a8033e407c"
        }
    ]
}
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": []
}

3回目のメッセージ受信。受信回数(ApproximateReceiveCount)が maxReceiveCount の 3 になっている。

# 3rd receive
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": [
        {
            "Body": "b",
            "Attributes": {
                "ApproximateReceiveCount": "3"
            },
            "ReceiptHandle": "0NNAq8PwvXuRAEX6o9P6QNdJUg4Y+kIYEDd4N+5gSBkTUuBeeLWtgVhow/UbbZQdRae4IiNl633xy+txSc6DaIJnhF4nCiNrDUqgTBAvrX7SplJepZULfbiFYQ7jIIOMUaRdiZdhzI7yZX7ym273+ZVjva2+BN2oHzuqBREfrDXdK1B6uYcn01N0oUDasPCEaNA/5oCpDyBAQN0dRjdXaEJoKHjdUbilzP8I7wzSwco6XYwrLetluMlqYh24jIpp+XsEHcec/C3vJ0LaQvwf1jVvWD41rIQatFgLo2wcVEs=",
            "MD5OfBody": "92eb5ffee6ae2fec3ad71c777531578f",
            "MessageId": "49d82701-d6d2-4b83-b0aa-77a8033e407c"
        }
    ]
}
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": []
}

4回目のメッセージ受信に突入。
maxReceiveCount を超えているので、メッセージは DLQ(test_dlq) にルーティングされている。

# 4th receive
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_q --attribute-names ApproximateReceiveCount
{
    "Messages": []
}
$ aws sqs receive-message --queue-url  https://sqs.ap-northeast-1.amazonaws.com/423000/test_dlq --attribute-names ApproximateReceiveCount
{
    "Messages": [
        {
            "Body": "b",
            "Attributes": {
                "ApproximateReceiveCount": "4"
            },
            "ReceiptHandle": "+eXJYhj5rDoLu427sHnYOtdJUg4Y+kIYY+QYOKj7fbZ79+sqSqQ6y59M9hfbMu0NrpFYGaSKVCgxanqLid4m0iUep2LgkA2rmaU+BjYqMMGNUIfHw7xoUM0I9Pbwcsp8TPDIrYQJfPOvpWUAnVUIiXlVJRo3fnw2ZcrRhEFLRU7hgG4z/z3RcQQrB7ZksChlJnwPr6yo9OVAQN0dRjdXaEJoKHjdUbilzP8I7wzSwco6XYwrLetluMlqYh24jIpp+XsEHcec/C3vJ0LaQvwf1vRAQqRpm1+fW3B7Pai+dqE=",
            "MD5OfBody": "92eb5ffee6ae2fec3ad71c777531578f",
            "MessageId": "49d82701-d6d2-4b83-b0aa-77a8033e407c"
        }
    ]
}

boto から触ってみる

Python バインディングの boto を使って、通常の queue を2つ(test_q1, test_q2)作り、dead letter queue の送り先に test_dlq を設定してみる。

実際に、実行してみる。

$ python create_dlq.py
queue attributes for test_q1
{u'ApproximateNumberOfMessages': u'0',
 u'ApproximateNumberOfMessagesDelayed': u'0',
 u'ApproximateNumberOfMessagesNotVisible': u'0',
 u'CreatedTimestamp': u'1393655431',
 u'DelaySeconds': u'0',
 u'LastModifiedTimestamp': u'1393655432',
 u'MaximumMessageSize': u'262144',
 u'MessageRetentionPeriod': u'345600',
 u'QueueArn': u'arn:aws:sqs:ap-northeast-1:423000:test_q1',
 u'ReceiveMessageWaitTimeSeconds': u'0',
 u'RedrivePolicy': u'{"deadLetterTargetArn":"arn:aws:sqs:ap-northeast-1:423000:test_dlq","maxReceiveCount":5}',
 u'VisibilityTimeout': u'30'}
queue attributes for test_q2
{u'ApproximateNumberOfMessages': u'0',
 u'ApproximateNumberOfMessagesDelayed': u'0',
 u'ApproximateNumberOfMessagesNotVisible': u'0',
 u'CreatedTimestamp': u'1393655431',
 u'DelaySeconds': u'0',
 u'LastModifiedTimestamp': u'1393655433',
 u'MaximumMessageSize': u'262144',
 u'MessageRetentionPeriod': u'345600',
 u'QueueArn': u'arn:aws:sqs:ap-northeast-1:423000:test_q2',
 u'ReceiveMessageWaitTimeSeconds': u'0',
 u'RedrivePolicy': u'{"deadLetterTargetArn":"arn:aws:sqs:ap-northeast-1:423000:test_dlq","maxReceiveCount":5}',
 u'VisibilityTimeout': u'30'}
dead letter source queues for test_dlq
[Queue(https://queue.amazonaws.com/423000/test_q1),
 Queue(https://queue.amazonaws.com/423000/test_q2)]

test_q1/test_q2 からは RedrivePolicy に test_dlq が設定されており、test_dql への送り元には test_q1test_q2 が設定されている。

メッセージの受信処理は変わらないので省略。

References

Tagged with: , ,
Posted in aws, middleware

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 6 days ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 3 weeks ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 3 weeks ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 6 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 9 months ago
%d bloggers like this: