web-dev-qa-db-ja.com

AWS SQSキューをポーリングし、受信したメッセージをキューから削除するためのベストプラクティスは?

データコンシューマーによって常に入力されているSQSキューがあり、Pythonのbotoを使用してSQSからこのデータをプルするサービスを作成しようとしています。

私が設計した方法では、10〜20個のスレッドがすべてSQSキューからメッセージを読み取ろうとし、データに対して実行する必要があること(ビジネスロジック)を実行してから、キューに戻って次のバッチを取得します。それらが完了したら、データの。データがない場合は、データが利用可能になるまで待機します。

このデザインについてはよくわからない2つの領域があります

  1. 長いtime_out値を指定してreceive_message()を呼び出すことで、20秒以内に何も返されない場合(最大許容)、再試行するだけですか?または、データが利用可能になったときにのみ返されるブロッキングメソッドはありますか?
  2. メッセージを受信して​​もキューから削除されないことに気付きました。メッセージを受信した後、キューから削除するために別のリクエストを送信する必要がありますか?少しやり過ぎのようです。

ありがとう

16
Mo.

receive_message()メソッドのロングポーリング機能は、SQSをポーリングする最も効率的な方法です。それがメッセージなしで返される場合、特に複数のリーダーがある場合は、再試行する前に少し遅らせることをお勧めします。増分遅延を実行して、後続の空の読み取りが少し長く待機するようにし、AWSによって抑制されないようにすることもできます。

はい、読んだ後にメッセージを削除する必要があります。そうしないと、メッセージがキューに再表示されます。これは、ワーカーがメッセージを読んだ後、メッセージを完全に処理する前に失敗した場合に、実際に非常に役立ちます。その場合、それは再キューイングされ、別のワーカーによって読み取られます。また、メッセージの非表示タイムアウトが、ワーカーがメッセージをキューに自動的に再表示する前に処理するのに十分な時間があるように設定されていることを確認する必要があります。必要に応じて、予想よりも時間がかかっている場合、ワーカーは処理中にタイムアウトを調整できます。

16
garnaat

メッセージの処理が終了したときのメッセージの自動削除、および指定されたキューへの例外の自動プッシュを含むリスナーを設定する簡単な方法が必要な場合は、 pySqsListener パッケージを使用できます。

次のようなリスナーを設定できます。

from sqs_listener import SqsListener

class MyListener(SqsListener):
    def handle_message(self, body, attributes, messages_attributes):
        run_my_function(body['param1'], body['param2']

listener = MyListener('my-message-queue', 'my-error-queue')
listener.listen()

ショートポーリングからロングポーリングに切り替えるフラグがあります。これはすべてREADMEファイルに記載されています。

免責事項:私は上記のパッケージの作者です。

6
ygesher

もう1つのオプションは、 このブログ投稿 で説明されているように、AWSBeanstalkを使用してワーカーアプリケーションをセットアップすることです。

Boto3を使用した長時間のポーリングの代わりに、flaskアプリケーションはメッセージをHTTPポストのjsonオブジェクトとして受信します。設定されているHTTPパスとメッセージのタイプは、AWS ElasticBeanstalkの[構成]タブで構成できます。

enter image description here

AWS Elastic Beanstalkには、デプロイメント管理の利点とともに、SQSキューのサイズの関数としてワーカーの数を動的にスケーリングできるという追加の利点があります。

This は、テンプレートとして役立つと思ったアプリケーションの例です。

5
nick_de_veaux