Amazon SQSのメッセージ削除に使われるReceiptHandleを調べてみた

Amazon SQSのメッセージ削除に使われるReceiptHandleを調べてみた

Clock Icon2025.02.25

はじめに

データ事業本部のkobayashiです。SQSを使ったサービス開発を行っている中でDeleteMessageでメッセージを削除するといった処理がありその際に必要なReceiptHandleについて調べてみたのでまとめます。

SQSキューのメッセージに使うReceiptHandleとは

標準キュー・FIFOキューともにSQSキューからメッセージを受信後に削除するにはDeleteMessageで削除を行いますが、その際に必要なのはキューのURLと受信時に受け取ったReceiptHandleになります。

https://docs.aws.amazon.com/cli/latest/reference/sqs/delete-message.html

ReceiptHandleは、その処理中のメッセージを一意に識別するために発行される文字列で、メッセージ送信時にレスポンスとして返ってくるMessageIDとは異なり、ReceiptHandleは同じメッセージであっても受信するたびに異なる値が生成されます。
ReceiptHandleの用途としては、

  • メッセージの削除
  • メッセージの可視性タイムアウトの変更

といった処理中のメッセージを追跡するために使われるものになります。

ではReceiptHandleを使ってメッセージの削除を行ってみます。

ReceiptHandleを使って受信したメッセージの削除とエラー

メッセージをキューから受信すると以下のようなレスポンスが返って来ますので、

{
    'Messages': [
        {
            'MessageId': '5afd1cec-30f0-44ac-a8ef-630e0c2f8775',  
            'ReceiptHandle': 'AQEBtXxdDE0GlBeXpbRzmq9ONt48lm0tq {中略} sjowerAdNwGzFC7e8UmY4',
            'MD5OfBody': '9a59e9b809714ff3d0c1ea34926044ea', 
            'Body': '{"hello": "world"}',
            ....
        }
    ]
}

この中のReceiptHandleを使って削除を行うことができます。

import botoe3

sqs_client = boto3.client("sqs")

sqs_client.delete_message(QueueUrl="message_url", ReceiptHandle="AQEBtXxdDE0GlBeXpbRzmq9ONt48lm0tq {中略} sjowerAdNwGzFC7e8UmY4")

その際にReceiptHandleが正しくないと以下のような「ReceiptHandleの有効期限が切れているよ」と言ったメッセージが表示されます。

botocore.exceptions.ClientError: An error occurred (InvalidParameterValue) when calling the DeleteMessage operation: Value AQEBtXxdDE0GlBeXpbRzmq9ONt48lm0t{中略}zFC7e8UmY4 for parameter ReceiptHandle is invalid. Reason: The receipt handle has expired.

これはReceiptHandleには有効期限があるために起こります。

ReceiptHandleの有効期限

ReceiptHandleはドキュメントに以下の記述があります。

Each time you receive a message, meaning when a consumer retrieves a message from the queue, it comes with a unique ReceiptHandle. If you receive the same message more than once, you will get a different ReceiptHandle each time.

DeleteMessage - Amazon Simple Queue Service

これはコンシューマがSQSキューからメッセージを受信するたびにReceiptHandleが新しくなるのでその新しいReceiptHandleでメッセージを削除する必要があるということです。したがって、あるメッセージをキューから受信した際に受け取ったReceiptHandleがあった際に可視性タイムアウト期間VisibilityTimeoutがすぎると同じメッセージを再受信するため新しいReceiptHandleが振られメッセージの再受信が行われます。ReceiptHandleの有効期限はVisibilityTimeoutと同一となります。

詳しい内容は以下のAWSブログでも言及されていますのでご確認ください。
https://repost.aws/ja/knowledge-center/sqs-receipt-handle-error

また再受信するまではReceiptHandleは変わらないため、可視性タイムアウトを延長するChangeMessageVisibilityの操作を行った場合は可視性タイムアウトの期間が延長された分、ReceiptHandleの有効期限も伸びることになります。

まとめ

AWS SQSでメッセージを削除する際に必要なReceiptHandleについて調べてみました。適切なエラーハンドリングと可視性タイムアウトの管理を行うことで、より信頼性の高いメッセージング処理を実装することができるのだと再認識しました。

最後まで読んで頂いてありがとうございました。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.