LoginSignup
7
2

More than 1 year has passed since last update.

AWS SQS sendMessageBatchとdeleteMessageBatchの処理の仕様について

Last updated at Posted at 2022-12-05

はじめに

先日AWSのSQSを使ってSQS内にあるメッセージを別のキューに送信した後に元のキューの処理済みメッセージを削除するシステムを構築した際に、そこで使用されていた2つのメソッドを検証したところ、要注意な仕様があったのでここにまとめておく。

目次

1. そもそもsendMessageBatch・deleteMessageBatchとは?

  • sendMessageBatchとは?
  • deleteMessageBatchとは?

2. 気をつけなければいけない仕様とは?

  • 一部処理に失敗しても、ステータスコード200が返ってくる場合がある
  • 特にこのケースには要注意

3. 一部処理に失敗したときに処理を分けるには?

  • Failedを活用する

そもそもsendMessageBatch・deleteMessageBatchとは?

sendMessageBatchとは?

  • 数多く存在するAWSのSQSに存在するメソッドの中の一つ。(参照:JavaScript API リファレンス

  • 指定されたキューに対して最大10個のメッセージを送信するというもの。

  • 似たようなものにメッセージを一件だけ送信するsendMessageが存在するが、そのバッチ処理バージョンがこれ。

  • このメソッドを呼び出すと、以下のように送信に成功したメッセージを失敗したメッセージをリストで返してくれる。

sendMessageBatchの結果
 SendMessageBatchResult {    //送信結果のオブジェクト
      Successful: SendMessageBatchResultEntryList;  //送信に成功したメッセージのリスト
      Failed: BatchResultErrorEntryList;  //送信に失敗したメッセージのリスト
 }

deleteMessageBatchとは?

  • このメソッドも数多く存在するAWSのSQSに存在するメソッドの中の一つ。(参照:JavaScript API リファレンス

  • 指定されたキューから最大10個のメッセージを削除するというもの。

  • このメソッドも似たようなものにメッセージを一件だけ送信するdeleteMessageが存在するが、そのバッチ処理バージョンがこれ。

  • このメソッドを呼び出すと、以下のように削除に成功したメッセージを失敗したメッセージをリストで返してくれる。

deleteMessageBatchの結果
DeleteMessageBatchResult {   //削除結果のオブジェクト
    Successful: DeleteMessageBatchResultEntryList;   //削除に成功したメッセージのリスト
    Failed: BatchResultErrorEntryList;   //削除に失敗したメッセージのリスト
}

気をつけなければいけない仕様とは?

一部処理に失敗しても、ステータスコード200が返ってくる場合がある

  • 注意しなければいけないのは、この二つのメソッドはバッチ処理で、まとめて処理するものであるということ。

  • そのため仮に10件処理したとして、そのうち2件なんらかの原因で処理に失敗したとしてもエラーが発生せず、ステータスコード200が返ってくる場合がある。

特にこのケースには要注意

  • 例えば、sendMessageBatchであるSQSにメッセージを10件送信した後にそのSQSからそれらのメッセージdeleteMessageBatchで削除するとする。

  • その場合、それぞれのメソッドは一部失敗したとしてもエラーにならないので、仮にsendMessageBatchに一部失敗したとしても、deleteMessageBatchで全件成功してしまう可能性がある。

  • つまり、「送信に失敗したのに削除されてしまったメッセージ」が存在してしまうことになる。

↓↓↓こんな感じ↓↓↓

一部処理に失敗してもエラーにならない
//たとえばtry~catchなどで例外処理をしてもcatchされない可能性がある
try{
    //sendMessageBatchは一部処理に失敗しても処理が続行され、エラーがでない
    var sendMessageBatchResult = sqs.sendMessageBatch(キューのURL, 送信対象のメッセージリスト);

    //sendMessageBatchで一部処理に失敗しても、以下の処理は実行される
    var deleteMessageBatchResult = sqs.deleteMessageBatch(キューのURL, 削除対象のメッセージリスト);
    
}catch(e){
    console.log("エラー");
}

一部処理に失敗したときに処理を分けるには?

  • デフォルトではエラーは出されない仕様なので、それぞれのメソッドが返してくれるオブジェクト内の失敗リスト(Failedリスト)を活用する

↓↓↓こんな感じ↓↓↓

エラー処理の例
//sendMessageBatchを実行して変数sendResultに代入
var sendResult = sqs.sendMessageBatch(キューのURL, 送信対象のメッセージリスト);

if(sendResult.Failed.length != 0){  //リストFailedの長さが0でなければ一部処理が失敗している
    throw new Error('一部送信に失敗しました');
}else{
    console.log("全件成功しました");
}

//deleteMessageBatchも同様
var deleteResult = sqs.deleteMessageBatch(キューのURL, 処理対象のメッセージ);

if(deleteResult.Failed.length != 0){  //
    throw new Error('一部削除に失敗しました');
}else{
    console.log("全件成功しました");
}
  • sendResult.Failed.lengthとdeleteResult.Failed.lengthにはそれぞれの失敗件数が格納される
  • これを活用すれば、何件処理に成功または失敗しているのかを表示させることも可能
     
  • また、sendMessageBatchで処理成功したメッセージリストだけをdeleteMessageBatchの対象にすれば、先ほどの「送信には失敗したけど削除には成功したメッセージ」を回避することができる
    ↓↓↓こんな感じ↓↓↓
一部処理に失敗してもエラーにならない
//sendMessageBatchは一部処理に失敗しても処理が続行され、エラーがでない
var sendMessageBatchResult = sqs.sendMessageBatch(キューのURL, 送信対象のメッセージリスト);

//sendMessageBatchで成功したメッセージだけを削除対象にすれば、送信に失敗したものが削除されることはない
var deleteMessageBatchResult = sqs.deleteMessageBatch(キューのURL, sendMessageBatchResult.Successful);
7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2