Amazon SQSのメッセージ削除に使われるReceiptHandleを調べてみた
はじめに
データ事業本部のkobayashiです。SQSを使ったサービス開発を行っている中でDeleteMessageでメッセージを削除するといった処理がありその際に必要なReceiptHandleについて調べてみたのでまとめます。
SQSキューのメッセージに使うReceiptHandleとは
標準キュー・FIFOキューともにSQSキューからメッセージを受信後に削除するにはDeleteMessageで削除を行いますが、その際に必要なのはキューのURLと受信時に受け取ったReceiptHandleになります。
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ブログでも言及されていますのでご確認ください。
また再受信するまではReceiptHandleは変わらないため、可視性タイムアウトを延長するChangeMessageVisibilityの操作を行った場合は可視性タイムアウトの期間が延長された分、ReceiptHandleの有効期限も伸びることになります。
まとめ
AWS SQSでメッセージを削除する際に必要なReceiptHandleについて調べてみました。適切なエラーハンドリングと可視性タイムアウトの管理を行うことで、より信頼性の高いメッセージング処理を実装することができるのだと再認識しました。
最後まで読んで頂いてありがとうございました。