it-swarm.com.de

Wie kann man entscheiden, ob eine API synchron oder asynchron sein soll?

Ich entwickle einen Dienst, der einige APIs über den Endpunkt REST Endpunkt) verfügbar macht. Ich habe eine API, die viel Zeit in Anspruch nehmen kann, z. B. 5 bis 10 Minuten, um den angeforderten Vorgang abzuschließen.

Ich schreibe auch die clientseitige Anwendung, die Multithread-fähig ist und mehrere Anforderungen gleichzeitig an den Server stellen kann. Wenn die Server-API synchron ist, kann der jeweilige Client-Thread immer noch hängen bleiben und auf die Antwort vom Server warten. Der Client steckt also nicht vollständig fest, sondern kann mit anderen Vorgängen fortfahren.

Ich verstehe, dass ich, wenn ich es asynchron mache, etwas mehr Arbeit für die Verwaltung des API-Betriebsstatus leisten muss, damit der Client den Betriebsstatus abrufen kann.

Trotzdem kann ich immer noch nicht entscheiden, ob ich diese Server-API synchron oder asynchron machen soll.

Auf welcher Basis entscheidet man sich, eine API synchron oder asynchron zu machen? Kommt es darauf an, wie lange der API-Vorgang dauern wird? Kommt es darauf an, ob der Client das Blockieren von Anrufen verarbeiten kann?

4
ryen

HTTP ist in dem Sinne synchron, dass jede Anforderung eine Antwort erhält, aber asynchron in dem Sinne, dass Anforderungen lange dauern und mehrere Anforderungen möglicherweise parallel verarbeitet werden. Daher werden viele HTTP-Clients und -Server asynchron implementiert, ohne jedoch eine asynchrone API anzubieten. Die Verwendung mehrerer Threads ist eine Möglichkeit, Asynchronität zu implementieren. Es gibt jedoch auch andere Möglichkeiten wie Rückrufe oder Ereignisschleifen.

Wenn Sie eine asynchrone API mit HTTP in dem Sinne wünschen, dass eine Antwort nicht sofort verfügbar ist, müssen Sie die Asynchronität explizit modellieren:

  • Wenn eine gültige Anforderung empfangen wird, antwortet der Server sofort mit einem Erfolgsstatus, höchstwahrscheinlich 202 Akzeptiert oder 303 Siehe Andere.
  • Das Backend bearbeitet den Job dann im Hintergrund (möglicherweise als separater Thread, möglicherweise als separater Server).
  • Die Antwort sollte beschreiben, wie der Status des Jobs überwacht und wie das Ergebnis abgerufen werden kann. Später kann der Client diese Informationen verwenden, um das Ergebnis abzurufen.

Es gibt eine Reihe von Techniken wie Long-Polling oder Chunked Transfer, um das Ergebnis zu pushen, sobald es von dieser Ressource verfügbar ist, erfordert jedoch im Allgemeinen die Zusammenarbeit des Kunden.

Die Alternative besteht darin, ein anderes Protokoll als HTTP zu verwenden, insbesondere ein Protokoll, bei dem Nachrichten keine Antwort benötigen. Innerhalb des Webstacks sind WebSockets ein solches Protokoll und ermöglichen es dem Server, eine Antwort zu einem späteren Zeitpunkt zu pushen. Die Verwendung solcher Protokolle bedeutet jedoch einen höheren Entwicklungsaufwand für Sie, da Nicht-HTTP-APIs keine Tools und keine Framework-Unterstützung bieten.

Da asynchrone APIs für alle Beteiligten komplizierter sind, sollten sie vermieden werden. Auch hier sind sie für asynchrone Clients oder Server nicht erforderlich. Die Modellierung der Asynchronität in Ihrer API ist geeignet, wenn:

  • die Anforderung startet einen Hintergrundjob, der möglicherweise schnell verarbeitet wird oder nicht
  • das Erstellen der Antwort dauert von Natur aus einige Zeit
  • sie können nicht garantieren, dass eine Antwort bereit ist, bevor der Client eine Zeitüberschreitung aufweist, wahrscheinlich in der Größenordnung von 10 bis 30 Sekunden.

Beispielsweise kann die Weboberfläche meines WLAN-Routers den Router neu starten. Dies dauert von Natur aus einige Zeit. Sie haben dies auf folgende asynchrone Weise implementiert:

  1. Ich fordere einen Neustart an.
  2. Der Server antwortet sofort mit einer Statusseite.
  3. Der Router startet den Neustart.
  4. Die Statusseite fordert kontinuierlich den Status im Hintergrund an. In den meisten Fällen läuft die Anforderung ab, da der Server noch nicht neu gestartet wurde.
  5. Der Router wird neu gestartet und der Server wird wieder online geschaltet.
  6. Bei der nächsten Statusanforderung sendet der Server eine Statusantwort, die nach dem Neustart abgeschlossen wurde, und leitet meinen Browser auf eine neue Seite weiter.
8
amon

Als Faustregel gilt, dass eine HTTP-Anforderung innerhalb von Millisekunden und nicht innerhalb von Minuten bearbeitet werden sollte. Sie sollten die Implementierungsdetails des Clients nicht kennen und sich nicht darum kümmern, wie er möglicherweise parallele Anforderungen verarbeiten kann oder nicht. Das größte Problem bei mehrminütigen Anfragen besteht darin, dass Sie die ganze Zeit über die Leitung halten müssen. Dies kann aus mehreren Gründen schwierig sein:

  • Netzwerk-Timeouts und Unterbrechungen können die Anforderung stören.
  • Der Client darf die Anforderung nicht herunterfahren oder abbrechen, was für bestimmte Clients schwierig sein kann, z. Dies ist nicht der Standardmodus für PHP.
  • Es macht es schwieriger, viele Anforderungen für den Client parallel zu verwalten, da er tatsächlich Ressourcen für jede Anforderung zuweisen und aufbewahren muss und die Anforderungsressource erst loslassen kann, wenn der Server den Auftrag abgeschlossen hat.

Sobald die Anforderung aus irgendeinem Grund unterbrochen wurde, kann der Client das Ergebnis des Vorgangs nicht mehr abrufen. Er muss denselben Prozess neu starten und wahrscheinlich mehrere Minuten warten, was zu einem Fehlerzyklus führt.

Das asynchrone Entwerfen der API macht dies wesentlich robuster. Der Kunde kann eine Job-ID speichern, wo immer er möchte, und kann andere Dinge tun. Es kann jederzeit wieder einchecken, was für den Kunden günstig ist. Es spielt keine Rolle, ob eine einzelne Anforderung aus irgendeinem Grund fehlschlägt, jede Operation kann ohne Statusverlust wiederholt werden.

1
deceze