2012-08-10 25 views
7

Pythonでbotoライブラリを使用してAmazon SQSメッセージを取得しています。例外的なケースでは、キューからメッセージを削除しないで、一時的な障害を回復するためのいくつかの変更を加えます。しかし、私は失敗したメッセージを常に受け​​続けることを望んでいません。私がしたいのは、3回以上受信した後にメッセージを削除するか、受信カウントが3以上の場合にメッセージを受け取らないことです。Pythonでbotoライブラリを使ってAmazon SQSでメッセージを受け取る方法は?

最もエレガントな方法は何ですか?

答えて

3

これには少なくとも2つの方法があります。

botoでメッセージを読むと、Messageオブジェクトまたはそのサブクラスが表示されます。 MessageオブジェクトはSQSが知っているすべてのメッセージ属性を含むdictである「属性」フィールドを持っています。 SQSが追跡することの1つは、メッセージが読み取られた回数の概算値です。したがって、この値を使用してメッセージを削除するかどうかを判断できますが、値の「概算」の性質に慣れていなければなりません。

また、メッセージIDをある種のデータベースに記録し、メッセージを読むたびにデータベースのカウントフィールドを増やすことができます。これは、メッセージが単一のプロセス内で常に読み取られている場合や、プロセス間で読み取り値を記録する必要がある場合はSimpleDBのように行うことができる場合は、単純なPython dictで行うことができます。

希望に役立ちます。

ここではいくつかのサンプルコードです:

>>> import boto.sqs 
>>> c = boto.sqs.connect_to_region() 
>>> q = c.lookup('myqueue') 
>>> messages = c.receive_message(q, num_messages=1, attributes='All') 
>>> messages[0].attributes 
{u'ApproximateFirstReceiveTimestamp': u'1365474374620', 
u'ApproximateReceiveCount': u'2', 
u'SenderId': u'419278470775', 
u'SentTimestamp': u'1365474360357'} 
>>> 
+0

ご返信ありがとうございます。私はbotoのドキュメントをスキミングしましたが、メッセージの受信カウントを得る手がかりを見つけることができませんでした。それがどこにあるか知っていますか?ところで、単純なローカルデータベースを持つことは、この問題を管理する私の別の方法ですが、まずは可能な限り受信カウントを得るように、単純にしておきたいと思います。 – huzeyfe

+0

構文例を追加できますか?私が何度もメッセージを読んで、message_instance.attributesを見ると、私が見つけたのは空の辞書です。 – tponthieux

1

は、それはいくつかの手順で行う必要があります。

  1. SQS接続を作成する: - sqsconnrec = SQSConnection(AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY)
  2. キュー・オブジェクトを作成する: - request_q = sqsconnrec.create_queue( "QUEUE_NAME")
  3. ロードキューメッセージ: - メッセージ= request_q.get_messages()
  4. 今あなたがメッセージオブジェクトの配列を取得したメッセージの合計数を見つけるために: - はちょうどLEN(メッセージ)を行う

は魅力的に機能します。

+0

ご注意いただきありがとうございますが、私はこれが私の場合ではないことを恐れています。私はlen(メッセージ)は必要ありません。特定のメッセージの受信カウントが必要です。 – huzeyfe

+1

はい、受信カウントを得るためにbotoに定義された機能はありません。私は、メッセージID、カウント数、メッセージ本文を持つローカルタプルを維持することをお勧めします。特定の時間の後にキューからメッセージをロードし、IDがタプルに存在するかどうかを確認します。はいの場合は受信カウントを増やします。受信カウントが3を超える場合はメッセージを削除できます。私はメッセージオブジェクトのディレクトリを見て、それは受信カウント機能を持っていません。あなたの問題に役立つことを願っています。 –

+0

これは私がこのオプションだけを持っていると思う代替ソリューションでした。ありがとうございます.. – huzeyfe

4

他の方法では、SQSキューのメッセージの最後に追加の識別子を付けることができます。この識別子は、メッセージが読み取られた回数のカウントを保持することができます。

サービスがこれらのメッセージを繰り返しポーリングしないようにしたい場合は、「デッドメッセージキュー」というキューをもう1つ作成し、しきい値を超えたメッセージをこのキューに転送できます。

1

読み取ったメッセージからApproximateReceiveCount属性を取得します。 (エラーメッセージを管理できるよりも)別のキューに移動するか、単に削除するだけです。

foreach (var message in response.Messages){ 
     try{ 
      var notifyMessage = JsonConvert.DeserializeObject<NotificationMessage>(message.Body); 
        Global.Sqs.DeleteMessageFromQ(message.ReceiptHandle); 
      } 
     catch (Exception ex){ 
      var receiveMessageCount = int.Parse(message.Attributes["ApproximateReceiveCount"]); 
      if (receiveMessageCount >3) 
       Global.Sqs.DeleteMessageFromQ(message.ReceiptHandle); 
      } 
     } 
2

AWSだけで、以下の手順に従って、このためのサポートを内蔵しています

  1. 不能キュー
  2. 「使用再駆動方針」をチェックすることで、ソース・キューのためのリドライブポリシーを有効を作成
  3. セット「3」または1〜1000
  4. の間の任意の値として「最大が受け取る」
  5. 「デッドレターキュー」のために、ステップ#1で作成したデッドレターキューを選択

どのように働くかは、メッセージがワーカーによって受信されるたびに、受信カウントが増加します。 「最大受信数」カウントに達すると、メッセージはデッドレターキューにプッシュされます。 aws consoleを介してメッセージにアクセスした場合でも、受信カウントは増加します。

ソースUsing Amazon SQS Dead Letter Queues

関連する問題