Laden...

ASP.NET Webservice Lifecycle

Erstellt von gollum9 vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.323 Views
G
gollum9 Themenstarter:in
84 Beiträge seit 2007
vor 17 Jahren
ASP.NET Webservice Lifecycle

Hallo,

ich bin momentan etwas irritiert von dem Lebenszyklus eines ASP.NET Webservice.

Und zwar war ich bisher der festen Überzeugung, dass ein Webservice - einmal gestartet - im Speicher des IIS geladen bleibt, bis er aus Gründen wie "aller Speicher belegt" oder "Neustart des IIS" runtergefahren werden muss. Also ein klassischer Serverprozess.

Jetzt zeigt aber die Praxis, dass der Kontruktor des Webservice fast vor jeder Ausführung einer Webmethod ausgeführt wird. Und zwar ohne jedes System.

Jetzt hab ich mich nochmal tiefer in das Thema eingelesen und immer wieder die Aussage gefunden, dass ASP.NET Applikationen generell "stateless" sind und es keinen Zusammenhang zwischen zwei nacheinanderfolgenden Aufrufen gibt - die Instanz des Webservice bei Aufruf1 also nicht dieselbe ist wie bei Aufruf2.

Ist das nicht aus Sicht der Performance völlig unsinnig bei fast jedem Aufruf den Webservice neu zu instanziieren?
Und was passiert, wenn ich den Webservice mit mehreren tausend Anfragen pro Sekunde bombardiere?

C
1.215 Beiträge seit 2004
vor 17 Jahren

Wenn ein- und dieselbe Instanz, einmal erstellt, nun gecached und für jeden Aufrufer gleichermassen verwendet würde, dann könnte es aber ordentlich krachen, wenn sich zwei Requests überschneiden und auf die selben Felder der Instanz zugreifen...
😉

Grüsse
Cord

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von gollum9
Ist das nicht aus Sicht der Performance völlig unsinnig bei fast jedem Aufruf den Webservice neu zu instanziieren?
Und was passiert, wenn ich den Webservice mit mehreren tausend Anfragen pro Sekunde bombardiere?

Da lacht er nur. 🙂

Im Ernst: Da wird nicht nur ein Objekt pro Call erzeugt. Die Zustandslosigkeit hingegen ist ein Performance-Vorteil, denn zustandslose Dienste lassen sich ohne Ende skalieren.

G
gollum9 Themenstarter:in
84 Beiträge seit 2007
vor 17 Jahren

Ok, danke für die Antworten 🙂

Was mich halt ursprünglich annehmen hat lassen, dass ich mit einer einzigen Instanz arbeite ist folgendes:

Ich habe sämtlichen Datenbank-spezifischen Code getrennt von meiner Business Logik und gekapselt in einer Abstrakten Fabrik (inkl. Singleton usw) um später einfach neue bzw. andere Datenbanken anbinden zu können.
Die Singleton Implementierung der Datenbankschnittstelle hat auch den großen Vorteil, dass ich die Datenbankverbindung offen halten kann über die Lebenszeit einer Anfrage hinaus.
Das Logfile (log4net 👍) beweist mir, dass ich tatsächlich mit ein und derselben Instanz der DB-Klasse arbeite.

Aus den obigen Erkenntnissen hätte ich jetzt aber eigentlich erwartet, dass, wenn der Vater-Prozess stirbt auch sämtlicher Speicher freigegeben wird?!
Hat MS sich da irgendeine Zwischenlösung implementiert, oder macht das der IIS oder hab ich irgendwas falsch verstanden?

1.274 Beiträge seit 2005
vor 17 Jahren

Ich habe sämtlichen Datenbank-spezifischen Code getrennt von meiner Business Logik und gekapselt in einer Abstrakten Fabrik (inkl. Singleton usw) um später einfach neue bzw. andere Datenbanken anbinden zu können.
Die Singleton Implementierung der Datenbankschnittstelle hat auch den großen Vorteil, dass ich die Datenbankverbindung offen halten kann über die Lebenszeit einer Anfrage hinaus.

Das eigene Implementieren einer Connection-Pooling Funktion ist nicht notwendig, da das Framework die Connection intern selber hält.

Siehe Connection Pooling

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

G
gollum9 Themenstarter:in
84 Beiträge seit 2007
vor 17 Jahren

Oh - sehr interessant. Danke für den Tip.

Ich brauche jedoch evtl. trotzdem diesen eigenen Connection Pool (bzw. eigentlich ist es kein Pool, sonder ich halte die akt. Connection solange, bis sich ein Parameter ändert - dann gibts ne neue), da ich unabhängig von ADO.NET sein muss.
Meinen "Connection Pool" kann ich also mit beliebigen Datenbanken einsetzen, da er mit einer abstrakten DB-Klasse arbeitet und ihm egal ist, was innerhalb dieser passiert.

Edit: Lustig fand ich in der MSDN die Aussage, dass bei Verwendung des ADO.NET Connection Pools die DB-Connection explizit geclosed werden soll, damit ADO.NET sie besser offenhalten kann^^ *g

The connection pooler periodically scans connection pools looking for unused connections that were not closed by Close or Dispose, and reclaims those it finds. If your application does not explicitly close or dispose of its connections, it can take quite a while for the connection pooler to reclaim them, so it is best to ensure that you explicitly call Close and Dispose in your connections.

1.274 Beiträge seit 2005
vor 17 Jahren

h - sehr interessant. Danke für den Tip.

Ich brauche jedoch evtl. trotzdem diesen eigenen Connection Pool (bzw. eigentlich ist es kein Pool, sonder ich halte die akt. Connection solange, bis sich ein Parameter ändert - dann gibts ne neue), da ich unabhängig von ADO.NET sein muss.
Meinen "Connection Pool" kann ich also mit beliebigen Datenbanken einsetzen, da er mit einer abstrakten DB-Klasse arbeitet und ihm egal ist, was innerhalb dieser passiert.

Dafür gibt es eine Klasse die eine Factory implementiert die dafür gedacht ist unterschiedliche Datenbanksysteme nutzen zu können.

Schwieriger ist es nur wenn du eine Datenbank nutzen möchtest die keine ADO.NET, OLEDB oder ODBC Treiber hat. Dann musst du halt selber dagegen implementieren.

Aber alle gängigen System haben eine Möglichkeit das du mittels Ado darauf zugreifen kannst.

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von gollum9
Aus den obigen Erkenntnissen hätte ich jetzt aber eigentlich erwartet, dass, wenn der Vater-Prozess stirbt auch sämtlicher Speicher freigegeben wird?!
Hat MS sich da irgendeine Zwischenlösung implementiert, oder macht das der IIS oder hab ich irgendwas falsch verstanden?

Der "Prozess" (die AppDomain...) stirbt ja nicht nach dem Service. Das wäre sehr teuer und langsam.

Die Service-Instance (!) wird nach jedem Call wieder freigegeben. Wenn du aber eine Singleton-Implementierung über den static-Weg gehst, dann bleibt dein Singleton solange am Leben, wie die AppDomain im IIS geladen bleibt (bzw. im Worker-Prozess).

Wann die AppDomain entladen wird - und damit auch dein Singleton verschwindet - ist Entscheidung des IIS. Das Entladen kann aber auch völlig unterbunden werden.