Pythonでbotoライブラリを使用してAmazonSQSメッセージを取得しています。例外的に、一時的な障害を回復するためにさらにいくつかの変更を加えるために、キューからメッセージを削除しません。しかし、私は失敗したメッセージを絶えず受け取り続けたくありません。私がやりたいのは、3回以上受信した後にメッセージを削除するか、受信回数が3回を超えた場合にメッセージを受け取らないことです。
それを行う最もエレガントな方法は何ですか?
Pythonでbotoライブラリを使用してAmazonSQSメッセージを取得しています。例外的に、一時的な障害を回復するためにさらにいくつかの変更を加えるために、キューからメッセージを削除しません。しかし、私は失敗したメッセージを絶えず受け取り続けたくありません。私がやりたいのは、3回以上受信した後にメッセージを削除するか、受信回数が3回を超えた場合にメッセージを受け取らないことです。
それを行う最もエレガントな方法は何ですか?
これを行うには、少なくとも2つの方法があります。
botoでメッセージを読むと、Messageオブジェクトまたはそのサブクラスを受け取ります。メッセージオブジェクトには、SQSが認識しているすべてのメッセージ属性を含むdictである「属性」フィールドがあります。SQSが追跡するものの1つは、メッセージが読み取られたおおよその回数です。したがって、この値を使用してメッセージを削除するかどうかを決定できますが、値の「おおよその」性質に慣れている必要があります。
または、ある種のデータベースにメッセージIDを記録し、メッセージを読み取るたびにデータベースのカウントフィールドをインクリメントすることもできます。これは、メッセージが常に単一のプロセス内で読み取られている場合は単純なPython dictで実行でき、プロセス間で読み取り値を記録する必要がある場合はSimpleDBなどで実行できます。
お役に立てば幸いです。
次にいくつかのサンプルコードを示します。
>>> 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'}
>>>
他の方法として、SQSキューのメッセージの最後に追加の識別子を配置することができます。この識別子は、メッセージが読み取られた回数のカウントを保持できます。
また、サービスがこれらのメッセージを何度もポーリングしないようにしたい場合は、「Dead Message Queue」というキューをもう1つ作成し、しきい値を超えたメッセージをこのキューに転送できます。
awsにはこれに対するサポートが組み込まれています。以下の手順に従ってください。
それがどのように機能するかは、メッセージがワーカーによって受信されるたびに、受信カウントが増加します。「最大受信数」カウントに達すると、メッセージはデッドレターキューにプッシュされます。awsコンソールを介してメッセージにアクセスした場合でも、受信カウントが増加することに注意してください。
読んだメッセージからExplicitReceiveCount属性を取得します。(エラーメッセージを管理できるよりも)別のキューに移動するか、単に削除します。
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);
}
}
それはいくつかのステップで行われるべきです。
魅力のように機能するはずです。