Wir verweisen auf eine proprietäre CLI-DLL von Drittanbietern in unserem .net-Projekt. Diese DLL ist nur eine Schnittstelle zu ihrer proprietären C ++ - Bibliothek. Unser Projekt ist eine asp.net (MVC4 / Web API) Webanwendung.
Die unmanaged C ++ - Bibliothek ist ziemlich instabil. Manchmal stürzt es mit z. hängende Zeiger. Wir haben keine Möglichkeit, es zu lösen, und mit dieser Bibliothek ist eine erstklassige Kundenanforderung.
Wenn die Anwendung abstürzt, antwortet der Anwendungspool in IIS nicht mehr. Wir müssen es neu starten, und das dauert ein paar Minuten (ja, so lange!).
Wir möchten, dass diese instabile DLL unsere Anwendung nicht abstürzt. Was ist der beste Weg, es zu tun? Können wir die CLI-DLL in einer separaten Anwendungsdomäne speichern? Wie?
Vielen Dank im Voraus.
Ich denke, jede Antwort auf diese Frage wird eine Art Arbeit sein.
Meine Problemumgehung besteht darin, nicht direkt mit der DLL von Ihrer Webanwendung aus zu interagieren.
Schreiben Sie stattdessen Ihre Anforderungen von der Webanwendung in eine Message Queue oder eine SQL-Tabelle. Sie können dann eine andere Anwendung haben, z. B. einen Windows-Dienst, der die Anforderungen liest, mit der DLL interagiert und die Ergebnisse dann für das Lesen Ihrer Webanwendung zurückschreibt.
Ich sage nicht, dass SQL / Message Queues der richtige Weg sind, ich denke mehr an den allgemeinen Prozessablauf.
Ich hatte genau dieses Problem mit einer Bibliothek eines Drittanbieters, die zum Zweck der Interaktion mit einem Hardware-Kopierschutz-Dongle auf geschützten Speicher zugegriffen hat. Es funktionierte gut in einer Konsole oder winforms App, aber stürzte wie verrückt, wenn von einer IIS-Anwendung aufgerufen.
Wir haben verschiedene Dinge ausprobiert, von denen einige in anderen Antworten auf dieser Seite erwähnt werden. Aber letztendlich war die beste Lösung für uns eine sehr alte Technologie - .Net Remoting . Ich weiß - es ist an diesen Tagen etwas verpönt. Aber es passt gut zu diesem speziellen Bedürfnis.
Der instabile Code wurde in eine Windows-Dienstanwendung gestellt. Die Webanwendung führte Remoting-Aufrufe für diesen Dienst aus, der die Befehle an die Drittanbieterbibliothek weiterleitete.
Ich bin mir sicher, dass Sie dasselbe mit WCF, Sockets usw. machen könnten. Aber das Remoting war schnell und einfach einzurichten, und da wir nur mit demselben Server sprechen, funktioniert es ohne das Öffnen von Ports. Es spricht nur über eine Named Pipe.
Es bedeutet einen zweiten Dienst neben der Webanwendung zu installieren, aber das war in meinem speziellen Anwendungsfall akzeptabel.
Wenn Sie etwas Ähnliches getan haben und der Code des Drittanbieters den Dienst tatsächlich abgestürzt ist, könnten Sie wahrscheinlich Code in Ihre Hauptanwendung schreiben, um ihn wiederherzustellen.
Vielleicht ist eine Prozessgrenze nützlicher als eine App-Domäne, wenn Sie instabilen Code zum Streiten haben.
Ich würde zuerst die Wiederverwendungsrate des IIS-Prozesses erhöhen, vielleicht schlägt der DLL-Code nach einer bestimmten Anzahl von Aufrufen fehl oder nachdem der Prozess eine bestimmte Menge an Speicherauslastung erreicht hat.
Informationen zur Konfiguration der IIS 7.0-Recyclingoptionen finden Sie hier: Ссылка
In Ihrem Fall würde ich den Prozess zu einem bestimmten Zeitpunkt recyceln, wenn Sie wissen, dass die Anwendung weniger belastet wird. Und nach einer bestimmten Anzahl von Anfragen (niedriger als der Standard) zu versuchen, "frisch" -Prozess die meiste Zeit zu haben.
Der Recycling-Prozess ist anmutig in dem Sinne, dass der alte Prozess nicht beendet wird, bis derjenige, der ihn ersetzen wird, bereit ist, so dass es keine merkliche Ausfallzeit geben sollte. Weitere Informationen zum Recycling-Mechanismus finden Sie hier: Ссылка
Wenn das Obige das Problem nicht löst, würde ich die Aufrufe in meinen eigenen Code schreiben, der die Ausführung des instabilen DLLs verwaltet.
Dieser Code sollte von den Fehlern wiederhergestellt werden, indem beispielsweise die fehlerhaften Aufrufe wiederholt werden, bis ein Ergebnis erhalten wird, und mit einem fehlerhaften Fehler fehlschlägt, wenn dies nach mehreren Versuchen nicht möglich ist.
Intern können die Aufrufe der Unstable-DLL in einem erstellten Thread erfolgen oder auch der Code könnte in einer neuen externen Programmdatei enthalten sein, die Sie mit Process.Start starten könnten.
Diese letzte Option hat mehr Overhead, aber es könnte Ihre einzige Option sein. Sehen Sie sich diese SO-Frage an, um weitere Informationen zu erhalten: Wie gehst du mit einem Thread um, bei dem ein Anruf unterbrochen wurde?
Ich schlage folgende Lösung vor.
Umschließen Sie diese DLL mit einer anderen Webanwendung. Kann einer der folgenden sein. Da Sie bereits Web-API verwenden, ist es am besten für Sie geeignet.
Kontrollieren Sie Ihren p-invoke-Code, damit Sie keinen Fehler haben? Siehe folgende Artikel.
Tags und Links .net asp.net iis unmanaged command-line-interface