Richtlinie: Design des Status für J2EE-Anwendungen
Diese Richtlinie erläutert Designmechanismen für die Statusverwaltung einer J2EE-Anwendung.
Beziehungen
Hauptbeschreibung

Einführung

Die effektive Verwaltung des Anwendungsstatus ist ein wichtiger Aspekt beim Design verteilter Anwendungen. Diese Richtlinie gibt einen Überblick über einige allgemeine Aspekte, die beim Design eines Anwendungsstatus berücksichtigt werden müssen, und über die Mechanismen für die Statusverwaltung in einer J2EE-Anwendung.

Aspekte der Statusverwaltung, die beim Design berücksichtigt werden müssen, sollten während der Ausarbeitungsphase des Projekts geklärt werden. Der Softwarearchitekt sollte allgemeine Strategien der Statusverwaltung im Rahmen der Aktivitäten prüfen, die im Zusammenhang mit Analyse & Design (Aktivität: Geeignete Architektur definieren) ausgeführt werden. Während der Architekturanalyse sollte der Softwarearchitekt Skalierbarkeit und Leistungsanforderungen der Anwendung prüfen, um zu ermitteln, welche Verfahren der Statusverwaltung verwendet werden müssen, damit die Anwendung die Leistungsziele erfüllen kann. Während das Design der Anwendung im Laufe der Ausarbeitungsphase optimiert wird, muss der Architekt J2EE-spezifische Design- und Implementierungsmechanismen in der Aufgabe: Designmechanismen identifizieren definieren, um Statusinformationen mit der Anwendung zu verwalten.

Wie im Abschnitt Konzept: J2EE-Implementierungskonfigurationen erläutert, können J2EE-Anwendungen aus mehreren logischen Schichten bestehen, die auf eine oder mehrere physische Schichten (Maschinen) verteilt sind. Nach einem kurzen technischen Überblick über die Statusverwaltung finden Sie in den übrigen Abschnitten dieser Richtlinie eine Erläuterung der verschiedenen Design- und Implementierungsmechanismen für die Statusverwaltung, die in den vielen Anwendungsschichten verwendet werden können.

Beachten Sie, dass die ausgewählten Mechanismen vom Softwarearchitekten als Teil des Softwarearchitekturdokument dokumentiert werden müssen und dass der Softwarearchitekt Richtlinien zur Verwendung dieser Mechanismen als Teil der projektspezifischen Designrichtlinien bereitstellen muss.

Technischer Überblick

Es gibt einen wachsenden Trend zum Erstellen von verteilten Anwendungen, die in der einen oder anderen Form mit dem Internet interagieren. Obwohl die zugrundeliegende Struktur des Internet von Natur aus ohne Status ist, ergibt sich häufig die Notwendigkeit der Statusverwaltung, wenn Geschäftsanwendungen erstellt werden. Betrachten wir das Beispiel einer Internet-Anwendung, in der ein Benutzer auf einen Link von Seite a zu Seite b klickt. Die Anwendung, die die Anforderung der Seite b verarbeitet, hat nicht mehr Zugriff auf die Informationen, die zur Verarbeitung der Seite a verwendet wurden. Dieses Verhalten kann für statische Webseiten akzeptabel sein, die meisten Geschäftsanwendungen benötigen jedoch einige Informationen über die vorherige Verarbeitung. Dies ist der Punkt, an dem die Mechanismen der von J2EE bereitgestellten Statusverwaltung ins Spiel kommen.

Transienter vs. persistenter Status

Bevor die Richtlinien der Statusverwaltung näher erläutert werden, ist es wichtig, die Arten der Statusinformationen voneinander zu unterscheiden. Statusinformationen können grob in zwei Kategorien unterteilt werden: transiente Statusinformationen (die nur so lange existieren wie die Anwendung aktiv ist) und persistente Statusinformationen (die auch nach Beendigung der Anwendung existieren).

Transiente Statusinformationen existieren so lange wie die Entität, in der sie gespeichert sind. Ein Beispiel sind Statusinformationen, die als Feld in einer gewöhnlichen Java-Klasse gespeichert sind. Wird der Container, der diese Klasse enthält, aus irgendeinem Grund beendet, gehen die Statusinformationen verloren, sofern die Daten nicht an anderer Stelle, z. B. auf einem Sicherungsserver repliziert wurden.

Der persistente Status existiert so lange wie der Datenspeicher, in dem die Statusinformationen verwaltet werden. Persistente Statusinformationen werden im allgemeinen in einer Datei oder Datenbank gespeichert und bei Bedarf von der Anwendung geladen. Änderungen der persistenten Statusinformationen müssen in die Datenbank zurückgeschrieben werden. Die Aspekte der Integrität und Wiederherstellbarkeit des persistenten Datenspeichers sollten konsistent sein mit denen der Daten, die über die Anwendung abgerufen werden. Ein Beispiel für den persistenten Status sind Informationen, die in einem Datenspeicher, beispielsweise in einer relationalen Datenbank, gespeichert sind.

Sitzungsstatus

Webclients müssen häufig in der Lage sein, mehrere Browseranfragen zu stellen und von Seite zu Seite zu navigieren, während sie clientspezifische Informationen, z. B. die Artikel in einem elektronischer Warenkorb, beibehalten. Webanwendungen erstellen dazu eine Sitzungs-ID und ordnen dieser Sitzungs-ID Sitzungsdaten zu. Die Sitzungs-ID und der zugehörige Status werden als Sitzungsstatus bezeichnet.

Der Sitzungsstatus entspricht den Daten, die der Interaktion eines bestimmten Clients mit einer Webanwendung während eines kurzen Zeitraums (Minuten oder Stunden anstatt Tage) zugeordnet sind. Daher entspricht der Sitzungsstatus kurzlebigen Daten, die im allgemeinen nach Ablauf eines Zeitlimitwerts gelöscht werden, um unnötigen Ressourcenverbrauch zu vermeiden.

Wie weiter unten erläutert, kann der Sitzungsstatus auf dem Client oder auf dem Server gespeichert sein. Aufgrund der Bedeutung des Sitzungsstatus in webbasierten Anwendungen stellt die J2EE-Plattform Mechanismen bereit, die speziell für die Verwaltung des Sitzungsstatus vorgesehen sind.

Grundlegende Persistenzmechanismen

Nachfolgend sind allgemeine Mechanismen aufgeführt, die die Webanwendungen zum Speichern des Status verwenden.

Cookies

Cookies sind kleine Textdateien, die auf webbasierten Clients gespeichert werden. Ein Server kann Cookies auf dem Client speichern. Nachfolgende Clientanfragen senden das Cookie an den Server und ermöglichen dem Server dadurch den Zugriff auf die im Cookie gespeicherten Statusdaten.

Im Zusammenhang mit Cookies sind einige Aspekte von Bedeutung:

  • Viele Benutzer glauben, dass Cookies die Sicherheit und/oder Vertraulichkeit beeinträchtigen und inaktivieren daher die Verwendung von Cookies.
  • Die Größe von Cookie-Headern ist begrenzt, folglich wird dadurch auch die Menge der Daten begrenzt, die gespeichert werden kann.
  • Von einigen Protokollen, z. B. WAP (Wireless Access Protocol), werden Cookies nicht unterstützt.
  • Wenn sich ein Client an einem anderen Standort (z. B. an einer anderen Maschine) anmeldet, sind die Cookies, die an seinem vorherigen Standort gespeichert wurden, nicht verfügbar.
  • Die Statusdaten müssen durch Zeichenfolgewerte darstellbar sein.

URL-Umschreibung

Die URL-Umschreibung ist ein Mechanismus, mit dem der Sitzungsstatus in die URLs integriert wird, die in jeder Seite referenziert werden. Wenn ein Webserver Seiten generiert, die an den Client zurückgegeben werden sollen, codiert er den Sitzungsstatus in den URLs der Seite. Wenn der Benutzer anschließend einen URL anklickt, werden die im URL gespeicherten Statusdaten an den Server zurückgesendet, so dass dieser den Sitzungskontext wiederherstellen kann. Ein ähnlicher Mechanismus verwendet verdeckte HTML-Felder. Im Zusammenhang mit diesen Mechanismen sind folgende Aspekte von Bedeutung:

  • Alle Seiten in einer bestimmten Sitzung müssen vom Server verwaltet werden, andernfalls kann der Server die Sitzung nicht aufrechterhalten.
  • Der Status geht verloren, wenn der Client den Browser beendet oder durch Eingabe eines URL oder über ein Lesezeichen zu einem bestimmten URL wechselt.
  • Wie bei Cookies sind die Statusdaten nicht mehr verfügbar, wenn sich der Client an einem anderen Standort anmeldet.
  • Wie bei Cookies müssen die Daten durch Zeichenfolgewerte darstellbar sein.

Flachdatei

Eine Flachdatei ist eine der einfachsten Methoden, um persistente Statusinformationen zu speichern. Nach der Initialisierung wird die Flachdatei gelesen, um die ursprünglichen Statuswerte zu erstellen. Jedesmal, wenn der Status geändert wird, muss die Datei neu geschrieben werden, um den Status zu speichern. Einige der Nachteile, die das Speichern des Anwendungsstatus in einer Flachdatei mit sich bringt, sind nachfolgend aufgeführt:

  • Die Skalierbarkeit der Anwendung wird beeinträchtigt, weil die Anwendung das Anwendungsobjekt sperren muss, um den Zugriff auf die globalen Daten zu verhindern, während die Variablen des Anwendungsstatus aktualisiert und erneut in die Flachdatei geschrieben werden.
  • In den meisten Fällen erfordert das Aktualisieren der Daten, dass die gesamte Datei neu geschrieben wird.
  • Flachdateien bieten im Fall eines Fehlers nicht immer die Möglichkeit zur Wiederherstellung.

XML

Das Speichern von persistenten Statusinformationen in einer XML-Datei ist eine Verbesserung gegenüber dem Speichern in einer Flachdatei. Einige Vorteile, die das Speichern des Anwendungsstatus in einer XML-Datei gegenüber dem Speichern in einer Flachdatei hat, sind nachfolgend aufgeführt:

  • Eine XML-Datei stellt eine Struktur bereit, die in einer Flachdatei nicht existiert.
  • Eine XML-Datei kann mittels Standard-APIs syntaktisch analysiert werden.
  • Eine XML-Datei ist im allgemeinen besser portierbar.

Datenbank

Das Speichern von persistenten Statusinformationen in einer Datenbank erlaubt maximale Wiederherstellbarkeit. Einige Vorteile, die das Speichern des Anwendungsstatus in einer Datenbank bietet, sind nachfolgend aufgeführt:

  • Die Gestaltung der Tabellen bietet eine Struktur.
  • Der gesamte Anwendungsstatus muss nicht neu geschrieben werden, wenn eine Anwendungsvariable aktualisiert wird. Nur die aktualisierten Informationen müssen neu geschrieben werden.
  • Die Konsistenz kann sichergestellt werden, indem die Wiederherstellung des Anwendungsstatus mit der Wiederherstellung der Produktionsdatenbank koordiniert wird.
  • In Situationen, die eine hohe Zuverlässigkeit erfordern, können für den Datenbankserver Cluster gebildet werden.

Der Zugriff auf die Datenbanken kann über die Java Database Connectivity (JDBC) API erfolgen. JDBC kann auch für den Zugriff auf andere tabellarischen Datenquellen, z. B. Arbeitsblätter, und für den Zugriff auf Flachdateien verwendet werden.

J2EE-spezifische Mechanismen

Die J2EE-Plattform stellt spezielle Mechanismen zur Statusverwaltung bereit. Dies sind übergeordnete Mechanismen, die so konfiguriert werden können, dass sie einen oder mehrere der bisher beschriebenen grundlegenden Mechanismen verwenden.

Servlet-Kontext

Servlets können den Servlet-Kontext verwenden, um Daten zu speichern, die für mehrere Clients und Clientsitzungen gültig sind.

Die im Servlet-Kontext gespeicherten Daten sind im wesentlichen globale Variablen für die J2EE-Anwendung. Folglich kann die Verwendung des Anwendungsstatus signifikante Auswirkungen auf das Anwendungsdesign haben. Der Softwarearchitekt muss während der Aufgabe: Designmechanismen identifizieren folgende Punkte berücksichtigen, um festzustellen, ob der Servlet-Kontext geeignet ist:

  • Der Servlet-Kontext kann in einem einzelnen Prozess verwaltet und folglich nicht von mehreren Servern (Clustern) gemeinsam genutzt werden. Wenn dies jedoch nicht mit den Erfordernissen der Skalierbarkeit der Anwendung übereinstimmt, dann muss der Architekt in Erwägung ziehen, den Status als Sitzungsstatus zu speichern.   
  • Der Servlet-Kontext ist Teil des Prozessspeichers, daher wird er normalerweise nach Beendigung des Prozesses nicht mehr verwaltet.
  • Mehrere Threads können auf die globalen Daten zugreifen. Durch Sperren und Synchronisation der globalen Daten kann die Skalierbarkeit der Anwendung beeinträchtigt werden.

HTTP-Sitzungsobjekt

Servlets und JSPs können die einer bestimmten Clientsitzung zugeordneten Daten im HTTP-Sitzungsobjekt speichern. Werden Daten in Sitzungsobjekten gespeichert, ergeben sich Fragen bezüglich des Problems, wie die Sitzungsdaten mehreren Servern verfügbar gemacht werden sollen. Einige Softwareanbieter bieten die Möglichkeit, die Clientanfragen an denselben Server weiterzuleiten. Diese Vorgehensweise ist auch als "Serveraffinität" bekannt.

Das HTTP-Sitzungsobjekt ist während der Verarbeitung der Clientanfrage auf dem Server verfügbar. Zwischen den Anfragen kann es auf dem Server gespeichert oder nicht gespeichert werden. Der Server könnte so konfigurierbar sein, dass er jeden der weiter oben beschriebenen grundlegenden Persistenzmechanismen verwenden kann, einschließlich des Speicherns des Sitzungsstatus in Cookies auf dem Client oder in Dateien oder in einer Datenbank auf dem Server. Er könnte auch die Möglichkeit bieten, die Sitzungsdaten im Speicher auf allen Servern zu replizieren.

Der Mechanismus wird durch Konfiguration des Servers ausgewählt. JSPs und Servlets werden unabhängig vom ausgewählten Mechanismus codiert und greifen auf das Sitzungsobjekt über eine API zu, die in der Servlet-Spezifikation angegeben ist.

Enterprise JavaBeans

Enterprise JavaBeans umfassen erweiterte Mechanismen zum Speichern des Status, die auf den weiter oben beschriebenen einfacheren Mechanismen basieren, z. B. Datenbanken und Dateien. Es werden Stateful-Session-Beans verwendet, um die einer bestimmten Clientsitzung zugeordneten Daten zu speichern, während Entity-Beans zum Speichern von Daten mit längerer Lebensdauer verwendet werden. In Richtlinie: Enterprise JavaBean (EJB) finden Sie eine Erläuterung des von den EJBs gespeicherten Status.

Design des Sitzungsstatus

Webclients müssen häufig in der Lage sein, mehrere Browseranfragen zu stellen und von Seite zu Seite zu navigieren, während sie clientspezifische Informationen, z. B. die Artikel in einem elektronischer Warenkorb, beibehalten. Webanwendungen erstellen dazu eine Sitzungs-ID und ordnen dieser Sitzungs-ID Sitzungsdaten zu.

Die Sitzungs-ID selbst wird mit Hilfe einer oder zweier Methoden auf dem Client gespeichert:

  • Cookie - der Clientbrowser sendet dieses Cookie bei jeder Anfrage an den Server, so dass der Server den Sitzungsstatus erneut herstellen kann.
  • URL-Umschreibung - in den URLs der Seiten, die der Server an den Client zurückgibt, werden die Sitzungs-IDs codiert. Wenn der Benutzer einen solchen URL anklickt, wird die Sitzungs-ID an den Server gesendet, so dass der Server den Sitzungsstatus wiederherstellen kann.

Der Server wird für die ausgewählte Lösung konfiguriert. Servlets und JSP sollten so codiert sein, dass sie unabhängig von der konfigurierten Methode arbeiten. Inbesondere sollten alle URLs mit der Methode HttpServletResponse.encodeURL() codiert sein. Diese Methode prüft, ob die URL-Umschreibung aktiviert ist und führt gegebenenfalls die Codierung aus.

Die einer Sitzungs-ID zugeordneten Daten können im HTTP-Sitzungsobjekt gespeichert sein, wo JSPs und Servlets Zugriff darauf haben, oder sie können in Session-Beans gespeichert sein.

Sowohl für die Sitzungs-ID als auch für die zugehörigen Daten sollte ein Zeitlimit festgelegt werden, damit Sitzungsdaten, die über einen längeren Zeitraum hinweg nicht genutzt wurden, nicht unbegrenzt Ressourcen verbrauchten. Der Architekt sollte einen geeigneten Zeitlimitwert wählen.

Auswahl des richtigen Mechanismus

Die Architekten sollten das Speichern des Sitzungsstatus im Client aufgrund der Einfachheit und der besseren Leistung in Erwägung ziehen. Wird der Status auf dem Client verwaltet und gespeichert, dann müssen die Server keine Ressourcen verbrauchen, um die Statusinformationen zu speichern oder deren Konsistenz sicherzustellen. Der Nachteil beim Speichern der Statusinformationen auf dem Client liegt darin, dass die Informationen jedesmal an den Server übertragen werden müssen, wenn sie benötigt werden, so dass die Netzlatenzzeit berücksichtigt werden muss. Außerdem müssen möglicherweise Sicherheitsaspekte beachtet werden, falls Sitzungsstatusdaten vorhanden sind, die dem Client nicht ungeschützt präsentiert werden dürfen. Eine mögliche Lösung kann in diesem Fall die Verschlüsselung sein.

Falls die Anwendung große Mengen an Sitzungsstatusinformationen hat, dann ist es im allgemeinen vorteilhafter, diese Statusinformationen auf dem Server zu speichern, wo in der Regel geringere Einschränkungen hinsichtlich Größe und Typ existieren.

Allgemein kann man festhalten, dass Sitzungsstatusinformationen, die sich auf die Präsentation beziehen, im HTTP-Sitzungsobjekt gespeichert werden sollten, während Stateful-Session-Beans die Statusinformationen enthalten sollten, die für die richtige Implementierung der Geschäftslogik erforderlich sind. Das Duplizieren von Statusdaten sollte vermieden werden. Verschieben Sie statt dessen duplizierte Statusdaten in das HTTP-Sitzungsobjekt, und übergeben Sie diese Daten, falls erforderlich, in der Session-Bean als Parameter bei Session-Bean-Methodenaufrufen.

Falls die auf dem Server gespeicherten Sitzungsdaten auch nach dem Ausfall eines Serverknotens verfügbar sein sollen, dann sollten Sie die Verwendung eines Mechanismus zur Persistenz oder Replikation der Sitzungsdaten in Erwägung ziehen.

Design des langlebigen Status

Sitzungsdaten eignen sich für kurzlebige Clientdaten, die nach Ablauf eines Zeitlimits verfallen. Möglicherweise werden jedoch auch Daten benötigt, die über einen viel längeren Zeitraum hinweg erhalten bleiben sollen.

Die richtige Vorgehensweise in Bezug auf diese Daten ist abhängig von der Art der Daten, die gespeichert werden. Cookies, Flachdateien, XML-Dateien und Datenbanken können verwendet werden. In Bezug auf den Datenbankzugriff ist im allgemeinen eine Entity-Bean die beste Lösung. Einzelheiten hierzu finden Sie unter Richtlinie: Entity-Bean.