ASP Tipp 4: Vermeiden Sie das Zwischenspeichern von nicht beweglichen Komponenten in den Objekten „Application“ oder „Session“

Während sich das Zwischenspeichern von Daten im Application- oder Session-Objekt empfiehlt, kann das Zwischenspeichern von COM-Objekten große Nachteile haben. Es liegt oft nahe, häufig verwendete COM-Objekte in das Application- oder Session-Objekt abzulegen. Leider führen viele COM-Objekte, darunter alle in Visual Basic 6.0 oder früher verfassten, beim Speichern des Application- oder Session-Objekts zu schwerwiegenden Engpässen.

Insbesondere nicht bewegliche Komponenten führen beim Zwischenspeichern im Application- oder Session-Objekt zu Leistungsengpässen. Eine bewegliche Komponente ist eine mit ThreadingModel=Both markierte Komponente, die den FTM (Free-threaded Marshaler) aggregiert, oder eine mit ThreadingModel=Neutral markierte Komponente. (Das neutrale Modell wird erstmals in Windows 2000 und COM+ verwendet.) Folgende Komponenten sind nicht beweglich:

  1. Freethread-Komponenten (es sei denn, sie aggregieren den FTM)
  2. Apartmentthread-Komponenten
  3. Singlethread-Komponenten

Konfigurierte Komponenten (Microsoft Transaction Server (MTS)/COM+-Bibliothek und Serverpakete/-anwendungen) sind nicht beweglich, es sei denn, sie sind neutralthreaded. Apartmentthread-Komponenten und andere nicht bewegliche Komponenten funktionieren am besten im Gültigkeitsbereich der Seite (d. h. sie werden auf einer einzelnen ASP-Seite erstellt und gelöscht).

In IIS 4.0 wurde eine mit ThreadingModel=Both markierte Komponente als beweglich angesehen. In IIS 5.0 reicht das nicht länger aus. Die Komponente muss nicht nur mit Both markiert sein, sondern muss auch den FTM aggregieren. Der Artikel zur Beweglichkeit beschreibt, wie mit der Active Template Library geschriebene C++-Komponenten dazu veranlasst werden, den FTM zu aggregieren. Wenn Ihre Komponente Schnittstellenzeiger zwischenspeichert, müssen auch diese Zeiger selbst beweglich sein oder in der COM-GIT (Global Interface Table) gespeichert sein. Wenn sich eine Boththread-Komponente nicht zum Aggregieren des FTM neu kompilieren lässt, können Sie sie als ThreadingModel=Neutral markieren. Wenn IIS keine Beweglichkeitsprüfung durchführen soll (d. h. wenn nicht bewegliche Komponenten nicht im Gültigkeitsbereich des Application- oder Session-Objekts gespeichert werden sollen), können Sie AspTrackThreadingModel stattdessen in der Metabasis auf True festlegen. Es wird davon abgeraten, AspTrackThreadingModel zu ändern.

IIS 5.0 gibt einen Fehler aus, wenn Sie versuchen, eine nicht bewegliche, mit Server.CreateObject erstellte Komponente im Application-Objekt zu speichern. Sie können dies durch Verwenden von <object runat=server scope=application …> in der Datei Global.asa umgehen. Davon wird aber abgeraten, da dies wie unten erläutert zu Marshalling und Serialisierung führt.

Was läuft beim Zwischenspeichern nicht beweglicher Komponenten schief? Eine nicht bewegliche, im Session-Objekt zwischengespeicherte Komponente „bindet“ das Session-Objekt an einen ASP-Arbeitsthread. ASP verwaltet einen Pool von Arbeitsthreads, die von Diensten angefordert werden. Normalerweise wird eine neue Anforderung vom ersten verfügbaren Arbeitsthread verarbeitet. Wenn eine Sitzung an einen Thread gebunden ist, muss die Anforderung warten, bis der verknüpfte Thread verfügbar wird. Hierzu eine Analogie, die dies möglicherweise verständlicher macht: Sie gehen zum Supermarkt, kaufen Lebensmittel und bezahlen für diese an Kasse 3. Danach müssen Sie beim Einkaufen in diesem Supermarkt jedes Mal an Kasse 3 bezahlen, selbst wenn die Schlangen an anderen Kassen kürzer sind, oder es Kassen ohne Warteschlangen gibt.

Das Speichern nicht beweglicher Komponenten im Gültigkeitsbereich des Application-Objekts wirkt sich noch negativer auf die Leistung aus. ASP muss einen Spezialthread erstellen, um nicht bewegliche Komponenten im Gültigkeitsbereich des Application-Objekts auszuführen. Dies hat zwei Konsequenzen: Alle Aufrufe müssen zu diesem Thread gemarshallt und alle Aufrufe müssen serialisiert werden. Marshalling bedeutet, dass die Parameter in einem freigegebenen Bereich des Arbeitsspeichers gespeichert werden müssen. Am Spezialthread muss eine kostspielige Kontextänderung durchgeführt und die Methode der Komponente ausgeführt werden. Die Ergebnisse werden in einen freigegebenen Bereich gemarshallt, und eine weitere kostspielige Kontextänderung gibt die Kontrolle an den Originalthread zurück. Serialisierung bedeutet, dass alle Methoden nacheinander ausgeführt werden. Es ist nicht möglich, dass zwei unterschiedliche ASP-Arbeitsthreads gleichzeitig Methoden an einer freigegebenen Komponente ausführen. Dadurch wird Parallelität, insbesondere auf Mehrprozessorcomputern, verhindert. Am schlimmsten ist aber, dass allen nicht beweglichen Komponenten im Gültigkeitsbereich des Application-Objekts ein Thread (der „Host-STA“) gemeinsam ist. Dadurch werden die Auswirkungen der Serialisierung noch verstärkt.

Schwirrt Ihnen der Kopf? Dann dürften diese allgemeinen Regeln helfen. Wenn Sie Objekte in Visual Basic (6.0) oder früher schreiben, zwischenspeichern Sie sie nicht im Application- oder Session-Objekt. Wenn Ihnen das Threading-Modell eines Objekts nicht bekannt ist, sollten Sie es nicht zwischenspeichern. Anstatt nicht bewegliche Objekte zwischenzuspeichern, empfiehlt es sich, diese auf jeder Seite zu erstellen und freizugeben. Die Objekte werden direkt auf dem ASP-Arbeitsthread ausgeführt, so dass es nicht zu Marshalling oder Serialisierung kommt. Die Leistung ist angemessen, wenn die COM-Objekte im IIS-Feld ausgeführt werden, und wenn das Initialisieren und Löschen der COM-Objekte nicht besonders zeitaufwendig ist. Beachten Sie, dass Singlethread-Objekte nicht auf diese Weise verwendet werden sollten. Seien Sie vorsichtig: VB kann Singlethread-Objekte erstellen! Wenn Sie Singlethread-Objekte auf diese Weise (z. B. als Microsoft Excel-Tabelle) verwenden müssen, sollten Sie keinen hohen Durchsatz erwarten.

ADO-Recordsets können problemlos zwischengespeichert werden, wenn ADO als Freethread-Komponente markiert ist. Verwenden Sie die Datei Makfre15.bat, um ADO als Freethread-Komponente zu markieren. Diese befindet sich in der Regel im Verzeichnis \\Programme\Gemeinsame Dateien\System\ADO.

Warnung ADO sollte nicht als Freethread-Komponente markiert werden, wenn Microsoft Access als Datenbank verwendet wird. Das ADO-Recordset muss außerdem abgetrennt sein. Wenn Sie die ADO-Konfiguration auf Ihrer Site nicht steuern können (z. B. wenn Sie als unabhängiger Softwarehersteller eine Webanwendung an Kunden verkaufen, die ihre eigenen Konfigurationen verwalten), ist es im Allgemeinen wahrscheinlich besser, Recordsets nicht zwischenzuspeichern.

Wörterbuchkomponenten stellen ebenfalls bewegliche Objekte dar. Das LookupTable-Objekt lädt Daten aus einer Datendatei und ist sowohl für Kombinationsfelddaten als auch Konfigurationsinformationen geeignet. Das PageCache-Objekt von Duwamish Books stellt ebenso wie das Caprock-Lexikon Wörterbuchsemantiken bereit. Diese Objekte oder Ableitungen davon können die Grundlage einer effektiven Zwischenspeicherungsstrategie bilden. Beachten Sie, dass das Scripting.Dictionary-Objekt NICHT beweglich ist und nicht im Gültigkeitsbereich eines Application- oder Session-Objekts gespeichert werden sollte.