„Deadlock detected“ gefolgt von „Only one usage of each socket address is normally permitted“

Viel Spaß beim Lesen des ersten „richtigen“ Artikels auf diesem Blog.

Wie es im Betrieb einer großen Anwendung eben ab und zu vorkommt, wird ein Patch des Lieferanten eingespielt. Ein Patch der eigentlich eine Menge Unannehmlichkeiten im täglichen Betrieb lösen sollte. Die Betonung sollte auf „lösen sollte“ liegen. Denn was unausweichlich geschehen musste, geschah. Zunächst funktionierte die Applikation noch einwandfrei. Doch am nächsten Tag, als mehrere hundert Konzernmitarbeiter begonnen haben mit der Anwendung zu arbeiten, begannen die Probleme.

Im gefühlten 15-Minuten-Takt verabschiedete sich die Applikation, der Application Pool der betroffenen Webseite startete sich neu.
Ein Blick in den Eventviewer zeigte folgende zwei Einträge:

…gefolgt von …

Nachdem die Applikation, wie bereits beschrieben, von einem Lieferanten stammt und wir keine Source-Einsicht haben, gestaltete sich die Recherche entsprechend schwierig. Wir stießen u.a. auf die folgenden Artikel:

http://support.microsoft.com/kb/821268

http://blogs.msdn.com/b/perfdude/archive/2008/09/21/web-server-deadlocks-aspnet-isapi-dll.aspx

http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx

In beiden Artikeln gibt es mehrere Lösungsansätze, die wir nach und nach probierten.

1. Ansatz: maxWorkerThreads und maxIoThreads
Beide Einstellungen sind in der machine.config zu treffen. Per Default sind diese beiden Settings jeweils auf 20 gesetzt. MaxWorkerThreads stellt ein, wieviele Threads ein Worker-Process offen halten darf/kann. Das gilt PRO WorkerProcess und nicht für alle WorkerProcesse bzw. global. Nachdem wir mittels TaskManager festgestellt haben, dass der betreffende WorkerProcess bis zu 45 Threads geöffnet hat, dachten wir hier auf der richtigen Spur zu sein. Microsoft empfiehlt bei stark frequentierten Webseiten nämlich jeweils die Einstellung 100. Ich werde den Artikel, aus dem ich diese Information habe nachreichen, sobald ich ihn wieder finde.  Diese Einstellung brachte leider keine Verbesserung. Die Applikation stürzte immer noch ab, jedoch benötigte der IIS länger um den Deadlock zu erkennen.

2. Ansatz: MaxUserPort und TIME_WAIT (Registry Settings; 3. Link).
Beide Einstellungen befinden sich in der Systemregistry unter HKLMSystemCurrentControlSetServicesTcpipParameters. Beim Setting sind „DWORD“s.  Mit MaxUserPort  kann man einstellen, wie groß die „Dynamic Port Range“ ist, was gleichbedeutent mit der Anzahl an Socket Addresses ist. Hier ist ein Wert zwischen 5000 (default) und 65534 zulässig. Um „auf der sicheren Seite zu sein“ und nach Empfehlung des Lieferanten haben wir hier gleich den Höchstwert verwendet.

TIME_WAIT stellt ein, wie lange die offene Connection im Status „TIME_WAIT“ verweilt. Ob diesese Setting für einen interessant ist, kann man ganz einfach mit dem Command-Shell-Befehl „netstat“ herausfinden. Befinden sich hier viele Connections im Status „TIME_WAIT“ so kann man diesen Wert herabsetzen. Default-Wert ist hier 4 Minuten. Im angesprochenen Artikel vorgeschlagen diesen Wert auf 30 Sekunden herabzusetzen.

Zu beachten gilt, dass beide Werte erst nach NEUSTART der Maschine übernommen werden!!

Nachdem auch diese Einstellungen nicht zur Verbesserung beitrugen und auch der Lieferant keine Lösung oder Lösungsansatz mehr parat hatte, haben wir uns entschieden nochmals zu patchen und eine „noch neuere“ Version einzuspielen. Die Probleme konnten dadurch gelöst werden, die eigentliche Ursache des Problems wird zumindest für uns im verborgenen bleiben.

Abschließend sollte erwähnt werden, dass der problembehaftete Patch ein halbes Jahr auf zwei Qualitätssicherungssystemen (erfolgreich) getestet wurde. Erst unter der Last von mehreren hundert Anwendern traten die Probleme auf…

Cheers,
Chris aka. der Weg ist das Ziel.

 

Comments ( 2 )

  1. kran kozlovoy

    Thank you for this valuable post. It changed my idea.

  2. chewcocker

    I'm glad I could help.

Leave a reply