API-Aufrufe mit Sellerie durchführen

8

Ich entwerfe ein System für einen Kunden, bei dem folgende Anforderungen gestellt werden:

  • Sie laden eine JSON-Datei hoch (ein Objekt / eine Zeile).
  • Rufen Sie eine API mit dem JSON-Objekt als Nutzlast auf
  • Notieren Sie den Status (Erfolg / Misserfolg) jedes API-Aufrufs in einer Datenbank
  • Führen Sie einen erneuten Versuch durch, wenn ein Fehler vorliegt.

Ich beschloss, es mit Sellerie und einer SQLite-Datenbank als Backend aufzubauen. Die Anzahl der JSON-Zeilen ist nicht groß - vielleicht höchstens ein paar Millionen - was in den Speicher passt. Ich habe alle einzelnen Komponenten in Ordnung (kann Dateien hochladen, kann Dateien lesen, API aufrufen, kann in Datenbank schreiben usw.), aber ich bin nicht sicher über die Gesamtarchitektur des Versands von Aufgaben mit Sellerie.

Angenommen, die Datei enthält N Zeilen, sollte ich:

Option A:

  1. Erstellen Sie N Objekte in der Datenbank mit einer resultSpalte (anfangs null).
  2. Erstellen Sie N Sellerie-Aufgaben und übergeben Sie die Objekt-ID als Parameter und Nutzlast
  3. Lassen Sie die Unteraufgabe die API aufrufen und das Ergebnisfeld des Objekts auf Erfolg / Misserfolg aktualisieren.
  4. Lassen Sie die Wiederholungsfunktion von Sellerie versuchen, die API im Fehlerfall erneut aufzurufen.

Option B:

  1. Erstellen Sie N Objekte in der Datenbank mit einer resultSpalte (anfangs null).
  2. Erstellen Sie 1 Sellerie-Aufgabe und übergeben Sie die gesamte Liste mit N Objekt-IDs und N Nutzdaten
  3. Durchlaufen Sie alle N Objekte und aktualisieren Sie die Datenbank bei jedem Schritt mit dem Ergebnis.
  4. Wenn die vorherige Aufgabe abgeschlossen ist, wird eine weitere einmalige Sellerie-Aufgabe ausgelöst, die die Datenbank für alle Objekte mit Fehlerergebnis liest und sie erneut versucht.

Ich bevorzuge Option A wegen seiner Einfachheit, aber ich weiß nicht, wie hoch die Anzahl der geplanten Sellerie-Aufgaben ist und ob der Broker (RabbitMQ) damit umgehen wird. Bei Option B besteht das große Risiko, dass alle folgenden Objekte niemals ausprobiert werden, wenn die Sellerie-Aufgabe aus irgendeinem Grund in einer Zeile M beendet wird.

Irgendwelche Gedanken zu diesen beiden oder ob es eine dritte bessere Alternative gibt?

user154706
quelle

Antworten:

1

Option A klingt nach dem richtigen Weg, da Sie Worker als API festlegen können, anstatt große Aufgaben zu erledigen, die nur ein einzelner Worker verwalten kann.

Ich habe ein sehr ähnliches Szenario mit Kombu und Sellerie:

  • Wir erhalten eine Nachricht, die durch eine Integration in eine RMQ-Warteschlange an RMQ gesendet wird
  • Wir haben ein Kombu Consumer Draining Events
  • Wenn ein Ereignis empfangen wird, führen wir den Rückruf aus (Post an lokale Python-Warteschlange)
  • Sellerie erhält die Nachricht über die Python-Warteschlange gesendet und verarbeitet
  • Sobald der Vorgang abgeschlossen ist, werden die Ergebnisse zurückgegeben und die Nachricht an einen Kombu-Produzenten weitergeleitet
  • Der Produzent sendet zurück an RMQ

Wie Sie sehen, verfolgen wir grundsätzlich den gleichen Ansatz wie Sie. Wir haben dies in der Produktion, das ungefähr 2000 Nachrichten pro Stunde ohne Probleme verarbeitet.

ZeroSoul13
quelle