SQSのDLQ監視メトリクスでNumberOfMessagesSentは使用してはいけない

AWS SQSアイキャッチ

Lambdaなどの関数処理に失敗したときに失敗したメッセージをDLQに入れる設計をすることがあります。
処理が失敗しているので、DLQにメッセージが入ったらすぐに解析作業をしたいですよね。
そこでDLQにメッセージが入ったら即座に通知するためにメトリクスの監視が考えられます。そこで見るべきメトリクスを誤って失敗したことがあるので共有のために記事を書きます。

目次

結論 ApproximateNumberOfMessagesVisibleを確認するべき

NumberOfMessagesSentはSQS間でのメッセージの移動が反映されません。つまり通常キューからDLQに移動したメッセージは反映されません。
ApproximateNumberOfMessagesVisibleはキュー間のメッセージの移動も反映されるメトリクスです。

NumberOfMessagesSentメトリクスについて

メトリクスの説明

SQSのメトリクスによると、キューに追加されたメッセージ数を確認する際はNumberOfMessagesSentを見るのがよさそうなことが書いてありました。

NumberOfMessagesSent
キューに追加されたメッセージの数。 レポート条件: 負でない値が報告されます。キューがアクティブな場合。 単位:カウント 有効な統計: 平均、最小値、最大値、合計、データサンプル (Amazon SQS コンソールのサンプル数として表示)

Amazon SQS の利用可能な CloudWatch メトリクス

ディベロッパーガイドの注意書き

しかし、DLQにメッセージが入ったにもかかわらずこのメトリクスが反応しなかったです。 トラブルシューティングとしてSQSのディベロッパーガイドを確認すると気になる記載を見つけました。

デッドレターキューの NumberOfMessagesSent と NumberOfMessagesReceived が一致しない 手動でデッドレターキューに送信したメッセージは、NumberOfMessagesSent メトリクスによってキャプチャされます。ただし、処理の試行が失敗した結果としてデッドレターキューにメッセージが送信された場合、メトリクスによってキャプチャされません。したがって、NumberOfMessagesSent と NumberOfMessagesReceived の値が異なることもあります。

SQS ディベロッパーガイド

普通にメッセージが入ったときはカウントされるけど、DLQとして移動してきたメッセージはカウントされないということでしょうか。

そのあたりの挙動はNumberOfMessagesSentとApproximateNumberOfMessagesVisibleの挙動の違いの項で見ていきます。

ApproximateNumberOfMessagesVisibleメトリクスについて

結局見るべきメトリクスはApproximateNumberOfMessagesVisibleでした。SQSのメトリクスからApproximateNumberOfMessagesVisibleの説明を抜粋します。

ApproximateNumberOfMessagesVisible
キューから取得可能なメッセージの数。 レポート条件: 負でない値が報告されます。キューがアクティブな場合。 単位:カウント 有効な統計: 平均、最小値、最大値、合計、データサンプル (Amazon SQS コンソールのサンプル数として表示)

Amazon SQS の利用可能な CloudWatch メトリクス

この説明だけだと、NumberOfMessagesSentと違いがあるようには見えない。

念のためDLQにメッセージが入ったことを検知したい旨をAWSサポートに確認したところ、ApproximateNumberOfMessagesVisibleを見るように案内がありました。両者の違いについて確認していきます。

NumberOfMessagesSentとApproximateNumberOfMessagesVisibleの挙動の違い

SQSのディベロッパーガイドが言う手動でデッドレターキューに送信したメッセージ処理の試行が失敗した結果としてデッドレターキューにメッセージが送信された場合を再現させるために下記2パターンの検証を行いました。

デッドレターキューの NumberOfMessagesSent と NumberOfMessagesReceived が一致しない 手動でデッドレターキューに送信したメッセージは、NumberOfMessagesSent メトリクスによってキャプチャされます。ただし、処理の試行が失敗した結果としてデッドレターキューにメッセージが送信された場合、メトリクスによってキャプチャされません。したがって、NumberOfMessagesSent と NumberOfMessagesReceived の値が異なることもあります。

SQS ディベロッパーガイド

それぞれのパターンでNumberOfMessagesSentとApproximateNumberOfMessagesVisibleのメトリクスを見ていきます。

Lambdaで失敗したメッセージをDLQに送信

LambdaにDLQを設定しておきます。Lambdaはわざと失敗するコードを書いておきました。アーキテクチャ図を記載しておきます。

Lambda-SQSアーキテクチャ図
図1 lambdaで失敗したメッセージをDLQに送信

メトリクスの挙動はこんな感じになりました。

SQSメトリクスのグラフでNumberOfMessagesSentを確認する
図2 NumberOfMessagesSentも反応している

NumberOfMessagesSentとApproximateNumberOfMessagesVisibleがそれぞれ反応しています。LambdaがDLQに送信する場合はNumberOfMessagesSentが計上されない条件処理の試行が失敗した結果としてデッドレターキューにメッセージが送信された場合には当たらないということがわかりました。 よく見ると、NumberOfMessagesSentは09:03に上がってきているのに対し、ApproximateNumberOfMessagesVisibleは09:05に上がってきました。少しラグがありますね。その差は2分なので実用にはそこまで影響はなさそうですが。

SQSで処理されなかったメッセージをDLQに送信

SQSでDLQの設定をしておき、最大受信数を少なくすることによりDLQに落とすようにしてみました。

SQS(通常キュー)-SQS(DLQ)のアーキテクチャ図
図3 SQSからDLQにメッセージを移動する

メトリクスの挙動はこんな感じになりました。

SQSメトリクスのグラフでNumberOfMessagesSentを確認する
図4 NumberOfMessagesSentは反応していない

予想通り、NumberOfMessagesSentは反応せず、ApproximateNumberOfMessagesVisibleは反応しています。ここでは2通DLQに入れているのでカウントが2になっています。
NumberOfMessagesSentが計上されない条件処理の試行が失敗した結果としてデッドレターキューにメッセージが送信された場合に当たるということがわかりました。

まとめ

NumberOfMessagesSent:LambdaでSQSに入れた場合は検知可能。SQS間で移動したメッセージは検知不可。
ApproximateNumberOfMessagesVisible:LambdaでSQSに入れた場合検知可能。SQS間で移動したメッセージも検知可能。
検証の結果、NumberOfMessagesSentのほうがApproximateNumberOfMessagesVisibleより2分早く反応した。
DLQの監視はApproximateNumberOfMessagesVisibleを利用する。

PR
当ブログはWordPressテーマSWELLを使用しています。非常に使いやすく、簡単にプロのようなデザインを使えるのでお勧めです!!

SWELL – シンプル美と機能性両立を両立させた、圧巻のWordPressテーマ

ランキング

ランキングに参加しています。クリックして応援いただけると嬉しいです。
にほんブログ村 IT技術ブログ クラウドコンピューティングへ
にほんブログ村
AWSランキング
AWSランキング

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次