Allgemein, Architektur, Web

Stateful vs. Stateless Web Services

9 July 2007 3 Kommentare

Es ist schon ein paar Tage her, als ich Zeuge einer kleinen Debatte unter Entwicklern wurde. Es ging um die Entwicklung eines Web Services, welches eine große Menge an Daten beliefern sollte. Während des Brainstormings über Spezifikationen und Parameter wurde auch darüber diskutiert, ob der Web Service stateful – also mit einer Session – oder stateless konzipiert werden soll.

Völlig parteilos – ich kenne beide Entwickler :-) – möchte ich diese zwei Design-Konzepte ein wenig aus meiner eigenen Betrachtungsweise durchleuchten. Auf gut englisch – my 2c…

Zunächst sollte man sich meiner Meinung nach der Natur des Web Services im Klaren sein. Konkret ist ein Web Service eine öffentliche Schnittstelle zum Aufruf einer entfernten Operation. Nun ist soetwas ja nicht das 8. Weltwunder – will heissen dass es viele weitere, zum Teil deutlich ältere Technologien gibt, die das gleiche bezwecken wollen – es seien hier nur RPC und CGI als prominente Beispiele erwähnt. Das Problem “stateful” vs. “stateless” stellt sich also nicht erst seit dem es Web Services gibt.

Einen entfernten Aufruf – den berüchtigten “Remote Call” durchzuführen ist mit der Web Services-Technologie mittlerweile kinderleicht. Remote operations zur Verfügung zu stellen ist mit dem .NET Framework zum Beispiel fast genauso kinderleicht. Umso mehr sind Entwickler dazu geneigt, diese Leichtigkeit der Verwendung mit “Leichtsinnigkeit” zu verwechseln. Denn die Tragweite der Entscheidungen über ein Web Service Design kann manchmal ungeahnte Züge annehmen.

Doch zurück zum Thema: Grundsätzlich wurden Web Services für den automatisierten (also maschinellen) Informationsaustausch geschaffen. Per Definition des W3C ist ein Web Service nämlich folgendes:

A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAPmessages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards.

So. Eine klare Ansage. Aber beim zweiten durchlesen wird auch schon deutlich, wo der eigentliche Knackpunkt liegt. Es geht um das Teilstück “…interoperable machine-to-machine interaction…”. De facto lässt sich daraus ableiten, dass in der Idealform jeder Rechner innerhalb eines Netzwerkes jeden Dienst und dessen Operationen ansprechen und verarbeiten kann. Das kann auch komplexere Szenarien unterstützen; z.B dass Rechner, die Dienste zur Verfügung stellen, ihrerseits zur Erfüllung ihres eigenen Dienstes einen oder mehrere andere Dienste in Anspruch nehmen. Weiterhin ist per Definition auch die Multiplizität eines Dienstes freigestellt – d.h. es kann einen oder mehrere gleichartige, oder sogar equivalent operierende Dienste geben, die auf einer oder mehreren Rechnern zur Verfügung gestellt werden.

Bevor es nun zu theoretisch wird, kann man die Gedankenspiele abkürzend auf einen Nenner bringen: Bei Web Services geht es um flexible Kommunikation. Die Operation wird demjenigen zur Verfügung gestellt, der Sie braucht und ist idealerweise jederzeit ersetzbar. Des Weiteren ist die Operation idealerweise kontextunabhängig – lässt sich also ohne weiteres im Verbund mit anderen Operationen aufrufen, um daraus eine neue, sog. “orchestrierte” Operation zu formen.

Ich laufe hier natürlich sehr in Gefahr, in das SOA-Thema auszuschweifen – also gleich weiter mit der Ableitung der Definition des Web Services zu Entscheidungshilfen beim Design von Web Services.

Jetzt, da man die “Natur” eines Web Services sich genauer vor Augen hält, lässt sich eindeutig sagen, dass Web Services per se kontextunabhängig sind – im Resultat also “stateless”. Der Begriff “stateless” ist hier sehr leicht mit “statisch” ersetzbar – soll es aber nicht sein. Ein Web Service ist nicht zwingend statisch, weil es keinen Zustand hat. Der Gedanke der Kontextunabhängigkeit manifestiert sich bei Web Services nahezu überall: Die SOAP-Spezifikation enthält z.B. zahlreiche Möglichkeiten, Meta-Daten mit den Daten zu einer Operation zu übertragen. Im .NET Framework wird standardmäßig bei jedem Web-Service-Methoden-Aufruf die Web-Service-Klasse selbst instanziiert – eindeutige Zeichen dafür, dass Web Services für kontextunabhängige Verwendung ausgelegt worden sind.

Ergo: Web Services sind erst mal von Haus aus “stateless”. Aber wieso spielen nun viele Entwickler mit dem Gedanken, einen Web Service “stateful” werden zu lassen? Das kann viele Unterschiedliche Gründe haben – in dem von mir geschilderten Fall war die Datenmenge der Vater des Gedanken. Es sei hier nur kurz in groben Zügen der Werdegang der Idee zum “stateful” Web Service beschrieben:

Zur Implementierung einer Suche frägt der Client mit variablen Parametern ein Satz von Daten an – die resultierende Datenmenge ist unglaublich groß (sagen wir mal mehrere tausend Datensätze mit einer großen Menge an Daten, sagen wir mal 1MB pro Datensatz). Die Abfrage und Beschaffung der Daten auf der Datenbank kostet sehr viel Zeit (sagen wir mal mehrere Minuten) und kostet unglaublich viel Ressourcen (sagen wir mal es ist eine alte, gebrechliche Datenbank mit wenig Skalierbarkeit). (Merkt man, dass ich nicht gut im Erfinden von Anforderungen bin?)

Um nun Ressourcen zu schonen und die Geschwindigkeit zu erhöhen, kann man eine Session einführen, die bei der initialen Such-Abfrage erstellt wird. Die Abfrage wird gegen die Datenbank ausgeführt, das Ergebnis in der Session gespeichert und nur ein Teil der Daten (sagen wir mal, die ersten hundert) an den Client zurückgeliefert. Sollte der Client in einem zweiten Aufruf mehr Datensätze verlangen, werden die in der Session gespeicherten Daten zurückgeliefert, anstelle eine neue Abfrage gegen die Datenbank abzusetzen.

Ich möchte an dieser Stelle den aufmerksamen Leser bitten, über die Sinnhaftigkeit dieser Idee – wie ich es getan habe – hinwegzusehen und sich nur auf die Thematik der Kontextbezogenheit zu konzentrieren – Danke.

Nun, in Konsequenz würde die Einführung einer Session folgende Auswirkungen haben:
Die Session müsste erstellt werden, ein Session-State-Service müsste die Sessions verwalten. Wie es mit Sessions so ist, wäre die Session nur begrenzt gültig – und damit auch der gewünschte Effekt in begrenztem Maße erreicht. Weiterhin müsste die Session-ID in jedem Aufruf mit übergeben werden – das Interface würde also mit noch mehr Meta-Daten beladen werden. Im Übrigen wäre der Aufruf der zweiten Operation (”gebe mir noch mehr Datensätze”) nur möglich, wenn zuvor die erste aufgerufen wurde.

All diese meiner Meinung nach unvorteilhafen Konsequenzen müsste man in Kauf nehmen, um das gewünschte Ziel zu erreichen. Ein ziemlich teurer Preis wie ich finde.

Mit zustandsbehafteten Web Services schafft man sich aus meiner Sicht den Flaschenhals “Session-Manager” an, erhöht u.U. die “Chattiness” der Kommunikation zwischen Client und Server und schreibt dem Client auch noch Regeln vor, wie er welche Operationen aufzurufen hat, damit er an das gewünschte Ergebnis kommt. Stellt man sich dieses Szenario auch noch in einer Umgebung vor, die für hohe Performance und Verfügbarkeit ausgelegt ist (z.B. im Cluster), kommen noch kleinere Hürden wie Persistierung der Sessions und Web Service Paralellität hinzu.

Alles in allem ist meiner Meinung nach – zumindest für das oben genannte Szenario – ein zustandsbehafteter Web Service
1. schwieriger zu implementieren
2. keine signifikante Alternative zur Steigerung des Datendurchsatzes
3. mit vielen Hürden bespickt (Session-Manager, Multi-Threading)
4. wesentlich schwerer skalierbar
5. für Clients um ein vielfaches komplexer in der Verwendung

Sofern es also nicht wirklich sehr gute Gründe für die Kontextbezogenheit bestimmter Web Service-Methoden gibt, gilt beim Design von Web Services für mein Dafürhalten die grundlegende Orientierung nach der eigentlichen technologischen Ausrichtung des Web Services – stateless.

3 Kommentare

  • Ed :

    Hallo Ilker,

    ich gebe Dir Recht: WebServices sollten stateless sein.

    In deinem genannten Szenario wird wieder versucht durch “Kreativität” ein Symptom zu bekämpfen – nicht die Ursache! Nach meiner Meinung ein Klassiker in der Softwareentwicklung.

    Wenn die Datenbank zu langsam ist: get it fixed!

    Bleibt die Frage des Datendurchsatzes als Bottleneck zwischen den Parteien. Nicht alle Rechner sind an ein entsprechendes Datennetz angebunden und verfügen nur über eine geringe Bandbreite. Eine Abfrage, wie von Dir genannt, könnte somit für den Client tötlich sein. Eine Idee wäre es dem Aufrufer eine Methode zur Verfügung zu stellen in welcher lediglich die Anzahl der Treffermenge ( ggfl. auch die kummulierte Datenmenge ) erhält. z.B. Resultsetcount=1000 Resultsetsize=1MB.
    Somit könnte der Client entsprechend reagieren und dem Benutzer die Wahl stellen ob dieser eine längere Wartezeit in anspruch nemhen möchte.

    Ich bleibe dabei: WebServices sollten stateless sein! Sowie Datenbanken Datenbanken bleiben sollen etc.

    Die Eierlegende-Woll-Milch-Sau gibt es in der Natur nicht und sie wird es in der Softwarewelt auch nie geben. Es ist das Gesamtsystem welches miteinander harmonieren muss, sonst wird es nicht funktionieren.

    In diesem Sinne.

    Gruß
    Ed

  • codegod :

    Hallo zusammen,

    ich würde mir garnicht die Frage stellen ob ein Webservice stateless oder stateful sein sollte (denn der ist per se stateless), sondern vielmehr ob für den genannten Use-Case die Verwendung eines Webservices sinnvoll ist.

    Es gibt ja nicht umsonst Protokolle die stateful sind, vielleicht würde es sich lohnen, wenn sich die beiden darüber Gedanken machten.

    Ciao,
    Matthias

  • KonstantinMiller :

    Hi! I like your srticle and I would like very much to read some more information on this issue. Will you post some more?

Ihre Meinung ist gefragt!

Sie können folgende Tags verwenden:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Dieser Blogs unterstützt Gravatare.
Falls Sie noch keines haben, können Sie Ihren persönlichen Avatar bei Gravatar erstellen.