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.
|