2015-06-19 2 views
6

Nach dem Lesen von Tonnen von Informationen im Internet über Azure WebJobs besagt Dokumentation, dass ein Job idempotent sein sollte, andererseits sagen Blogs, dass sie WebJobs verwenden, um Aktionen wie "einen Kunden berechnen" oder "eine E-Mail senden" auszuführen. .Wie können fortlaufende Azure-Web-Jobs idempotent sein und E-Mails senden?

This documentation besagt, dass das Ausführen eines fortlaufenden WebJobs für mehrere Instanzen mit einer Warteschlange dazu führen kann, dass es mehrmals aufgerufen wird. Meiden die Leute wirklich die Tatsache, dass sie ihren Kunden zweimal belasten oder zweimal eine E-Mail senden können?

Wie kann ich sicherstellen, dass ich einen WebJob mit einer Warteschlange in einer skalierten Webanwendung ausführen kann und Nachrichten nur einmal verarbeitet werden?

Antwort

1

Ich mache dies mit einer Datenbank, eine Update-Abfrage mit einer Zeilensperre und TransactionScope-Objekt.

Erstellen Sie in Ihrer Auftragstabelle eine Spalte, um den Status der Aktion zu verwalten, die Sie in Ihrem WebJob ausführen. d.h. EmailSent.

In der QueueTrigger-Funktion beginne eine Transaktion und führe dann eine UPDATE-Abfrage für die Kundenbestellung mit ROWLOCK aus, die EmailSent = 1 mit einem WHERE EmailSent = 0 setzt. Wenn der Rückgabewert von SqlCommand = 0 ist, dann die Funktion beenden. Ein anderer WebJob hat die E-Mail bereits gesendet. Andernfalls senden Sie die E-Mail und rufen Complete() für das TransactionScope-Objekt auf, wenn sie erfolgreich gesendet wurde.

Das sollte die gewünschte Idempotenz bieten.

Hoffe, dass hilft.

+1

Ich dachte dies als meine letzte Lösung. Wie werden die Fehler verwaltet? Wenn einer der Server ohne Fehler auskommt und keine E-Mail gesendet wird, wird der andere Server nicht abgeschlossen und hat einen Fehler. Wie wird der Fehler hier verwaltet? Wird es erneut auslösen? Gehe zu Gift? oder den Fehler vollständig ignorieren? Ich denke, das ist ein halbes Feature von Microsoft. Die Sperre sollte auf SDK-Ebene implementiert werden. – jsgoupil

+0

Ich weiß, dass dies eine alte Frage ist, aber Sie können zusätzlich einen Zeitstempel zu dieser Tabelle hinzufügen, so dass Sie protokollieren können, wenn sie gesperrt wird. Wenn dieser Zeitstempel mehr als X Minuten alt ist, nehmen Sie an, dass er fehlgeschlagen ist und löschen Sie die nächste Nachricht es. Sie haben Recht, dass dies im SDK nicht vollständig implementiert ist, aber dies ist nicht etwas, das das SDK selbst verarbeiten kann, da jede Situation anders ist. Ich meine, was ist, wenn Sie keine SQL Server-Datenbank haben? Sie müssen offensichtlich eine andere Lösung haben. Und wie soll das SDK wissen, was der Umfang der Idempotenz ist? Auch dies ändert sich von Fall zu Fall. – Jaxidian