Bewährte Verfahren für asynchrone Servlets
Das Feature für asynchrone Servlets ermöglicht Ihnen, eingehende Anforderungen und Antworten zu verarbeiten, ohne an den ursprünglichen Thread, über den die Anforderung eingeleitet wurde, gebunden zu sein.
Berücksichtigen Sie bei der Verwendung asynchroner Servlets die folgenden bewährten Verfahren:
- Anwendungen sollten nicht für jede erforderliche asynchrone Operation einen neuen Thread starten. Die Anwendungen sollten mindestens einen Thread-Pool oder die Methode "AsyncContext start(Runnable)" verwenden.
- Auf der Client-/Browserseite können Sie AJAX verwenden, damit bestimmte Teile der Seite asynchron aktualisiert werden können.
- Der Servletcontainer stellt sicher, dass auszuführende oder zuzuteilende Aufrufe erst dann gestartet werden, wenn der Web-Container-Thread, der den Befehl startAsync eingeleitet hat, vorhanden ist. Der Servletcontainer verarbeitet mehrere Threads jedoch nicht gleichzeitig über dieselbe Anforderung und dieselbe Antwort. Die Anwendung kann in diesem Fall ihre eigenen Parallelitäts- oder Synchronisationsprobleme behandeln, was jedoch nicht empfohlen wird, weil diese Vorgehensweise für Deadlock- oder Konkurrenzsituationen anfällig ist. Falls die Zuteilungs- oder Beendigungsmethode über einen vom Kunden erstellten Thread oder ein Runnable-Objekt, das mit "start(Runnable)" gestartet wurde, aufgerufen wird, kann die Zuteilung bzw. Beendigung sofort in einem neuen Thread gestartet werden, und alle weiteren Änderungen der Anforderung oder Antwort über den Thread, der diese Aufrufe eingeleitet hat, sind risikoreich. Zwei Threads haben Zugriff auf die Anforderung und die Antwort, was kann zu unbestimmten Ergebnissen führen kann, wenn beide Threads diese Objekte ändern. Rufen Sie deshalb nach einer Zuteilung keine Methoden in der Anforderung bzw. Antwort über denselben Thread auf, der auch die Zuteilung eingeleitet hat. Rufen Sie nach dem Aufruf einer Beendigungsoperation keine Methoden in der Anforderung bzw. Antwort auf.
- Asynchrone Listener haben eine Methode "onTimeout", die gestartet wird, wenn ein Zeitlimit für die asynchrone Operation erreicht wird.
Die asynchrone Operation kann jedoch weiterhin in einem Thread aktiv sein, während die Methode "onTimeout" in einem anderen Thread ausgeführt wird.
Dieses Szenario ist das gängigste, in dem mehrere Threads versehentlich gleichzeitig dieselbe Anforderung und Antwort verwenden.
Eine einfache Lösung für dieses Szenario ist die Verwendung einer gemeinsam genutzten Methode
"AtomicBoolean" im AsyncListener und in der asynchronen Methode:
Bei dieser Lösung kann nur ein einziger Thread den Schreibzugriff auf die Antwort erhalten.AtomicBoolean isOkayToRun = (AtomicBoolean) request.getAttribute("isOkayToRun"); if (isOkayToRun.setAndGet(false)){ // Zuteilung vornehmen }
- Der Web-Container versucht, alle Runnable-Objekte, die von Aufrufen an die Methode "start(Runnable)" in die Warteschlange eingereiht wurden, abzubrechen, wenn das Zeitlimit erreicht ist. Runnable-Objekte, die bereits gestartet wurden, können jedoch nicht unterbrochen werden, weil diese Unterbrechung zu Speicherverlusten führt.
- Die Anzahl der Threads, die Zeitlimitbenachrichtigungen absetzen, ist gering. Der Versuch, eine rechenintensive Operation oder Schreiboperation über ein Zeitlimit auszuführen, wird nicht empfohlen, weil selbst eine kleine Schreiboperation eine Weile dauern kann, wenn der Client eine langsame Verbindung hat. Wenn Sie das Zeitlimit für asynchrone Operationen inaktivieren, ist es einfacher, Fehler des Typs "OutOfMemory" zuzulassen oder zuzulassen, dass die Anzahl der TCP-Kanalverbindungen nicht ausreicht. Das Standardzeitlimit sind 30 Sekunden.
- Sie können verschiedene asynchrone Servletoptionen, wie z. B. Zeitlimiteinstellungen und die Methode "AsyncContext start(Runnable)", in der Administrationskonsole konfigurieren, indem Sie auf klicken. Weitere Informationen zum Konfigurieren des Web-Containers finden Sie im Artikel "Einstellungen des Web-Containers".
Wichtig: Asynchronous Request Dispatcher (ARD) und Remote Request Dispatcher (RRD) werden bei der Verwendung
asynchroner Servlets nicht unterstützt.
Tipp: Sehen Sie sich den Artikel zu den Zählern für Webanwendungen an, um mehr über Metriken für
asynchrone Servlets zu erfahren.