9 Stimmen

Verarbeitung von SQS-Warteschlangen mit Boto

Ich habe ein Python-Skript, das die Boto-Bibliothek auf einer EC2-Instanz verwendet, die Teil einer Autoscaling-Gruppe ist. Das Skript verarbeitet Nachrichten aus einer SQS-Warteschlange:

import boto
from boto.sqs.message import Message

conn = boto.connect_sqs()
q = conn.create_queue('queue-name')

while (qin.count() > 0):
    m = q.get_messages()
    #do something with the message

Macht es Sinn, die while-Anweisung zu verwenden? Wird count() in Echtzeit aktualisiert, wenn:

  1. andere Instanzen Nachrichten aus der Warteschlange abrufen (oder werde ich sie doppelt erhalten)
  2. neue Nachrichten zur Warteschlange hinzugefügt werden (oder werde ich sie verpassen?)

Wie kann ich dieses Skript dazu bringen, ständig nach neuen Hinzufügungen zur Warteschlange zu lauschen, selbst wenn die Warteschlange leer ist?

In dieser Frage Verarbeitung von Elementen in der SQS-Warteschlange mit einem PHP-Skript wurde erwähnt, dass die 'sqs ruby client library' eine Methode "poll" hat, die die Warteschlange kontinuierlich abfragt und bei Empfang einer Nachricht in der Warteschlange diese an einen Block weitergibt. Gibt es einen äquivalenten Ansatz in Python?

Es wurde auch vorgeschlagen, dass SNS verwendet werden könnte, um die Skripts über den Status der Warteschlange zu informieren, aber ich sehe nicht, wie man ein reaktionsfähiges System mit SNS konfigurieren könnte, da die Metrik-Alarme nicht feinkörnig genug sind.

7voto

garnaat Punkte 41136

Sie sollten sich nicht auf die Anzahl in einer Warteschlange verlassen, da sie nur dazu dient, eine ungefähre Anzahl anzugeben und nicht garantiert genau ist.

Wenn Sie einfach immer weiter abfragen möchten, tun Sie einfach dies:

while 1:
    messages = q.get_messages()
    # etwas mit den Nachrichten machen
    time.sleep(N)

Ich habe den Aufruf von time.sleep hinzugefügt, um eine Verzögerung in der Schleife zu erzeugen. Der Wert von N sollte mindestens eine Sekunde betragen und je nachdem, wie schnell Sie erwarten, dass neue Nachrichten in Ihrer Warteschlange erscheinen, auch erheblich mehr sein. Wenn Sie keine Verzögerung in die Schleife einfügen, werden Sie wahrscheinlich vom Dienst gedrosselt.

Um zu verhindern, dass eine Nachricht mehrmals gelesen wird, sollten Sie versuchen, die Sichtbarkeitszeit in der Warteschlange auf einen Wert einzustellen, der größer ist als die Zeit, die Sie benötigen, um eine Nachricht zu verarbeiten, und dann sicherstellen, dass Sie die Nachricht löschen, wenn die Verarbeitung abgeschlossen ist.

5voto

raulfortes Punkte 109

Beispiel:

# wait_time_seconds zählt nur 1 Anfrage in x Sekunden (0 - 20)
# num_messages erhält x Nachrichten in der gleichen Anfrage (1 - 10)
while 1:
    logger.info("... warte auf Nachrichten ...")
    messages = queue_in.get_messages(wait_time_seconds=20, num_messages=10)
    for message in messages:
        logger.info('Nachricht: %s' % (message,))
        queue_in.delete_message(message)

3voto

tyleha Punkte 3159
  1. Wenn Sie eine Nachricht aus SQS abrufen, wird die Nachricht unsichtbar und für andere Warteschlangenabfragen unerreichbar (Bearbeitung - die Unsichtbarkeit kann zwischen 0 und 12 Stunden eingestellt werden).
  2. Sie müssen die Warteschlange jedes Mal erneut abrufen, wenn neue Nachrichten hinzugefügt werden, aber das sollte kein Problem sein - dafür gibt es den Warteschlangendienst schließlich.

Wenn Sie die Warteschlange ständig abfragen möchten, versuchen Sie es mit dem sogenannten Long Polling - Sie können eine kontinuierliche Abfrage für bis zu 20 Sekunden haben, die zurückgegeben wird, wenn die Warteschlange befüllt ist.

Hoffentlich ist das hilfreich, ansonsten stöbern Sie in der boto sqs Dokumentation.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X