![[AIX Solaris HP-UX Linux Windows]](../images/dist.gif)
![[IBM i]](../images/iseries.gif)
Richtlinien für die ORB-Optimierung
Verwenden Sie die in diesem Dokument beschriebenen Richtlinien, wenn der ORB (Object Request Broker) an der Verteilung der Arbeitslast beteiligt ist.
Der ORB wird verwendet, wenn Enterprise-Beans über eine ferne Schnittstelle aufgerufen werden. Falls die CPU-Belegung sehr hoch oder sehr niedrig ist, könnten das Problem auf den Wert einer der folgenden Parameter zurückzuführen sein. Überprüfen Sie die folgenden Basisoptimierungsparameter bei jeder Anwendungsimplementierung.
Anpassung des Thread-Pools
Größe
Passen Sie die Größe des ORB-Thread-Pools an die Auslastung an. Das Aussetzen von Threads, falls keine Aufgaben zur Verarbeitung anstehen, sollte vermieden werden. Wenn für Threads keine Aufgaben bereit sind, wird CPU-Zeit verbraucht, weil die Methode "Object.wait" aufgerufen und damit ein Kontextwechsel durchgeführt wird. Optimieren Sie die Größe des Thread-Pools so, dass die Wartezeit der Threads kurz genug ist, um zu verhindern, dass sie gelöscht werden, weil sie zu lange inaktiv sind.
Die Größe des Thread-Pools richtet sich nach der Auslastung und dem System. In einer typischen Konfiguration benötigen Anwendungen maximal 10 Threads pro Prozessor.
Wenn Ihre Anwendung eine sehr langsame Back-End-Anforderung ausführt, wie z. B. eine Anforderung an ein Datenbanksystem, wird ein Server-Thread blockiert und wartet auf den Abschluss der Back-End-Anforderung. Bei Back-End-Anforderungen ist die CPU-Auslastung relativ gering. In diesem Fall führt eine erhöhte Arbeitlast weder zu einer erhöhten CPU-Auslastung noch zu einem höheren Durchsatz. Die Threadspeicherauszüge zeigen, dass fast alle Threads in Aufrufen an die Back-End-Ressource gebunden sind. In einem solchen Fall sollten Sie die Anzahl der Threads pro Prozessor so weit erhöhen, bis sich der Durchsatz verbessert und die Threadspeicherauszüge zeigen, dass die Threads auch in anderen Bereichen der Laufzeitumgebung außer den Back-End-Aufrufen aktiv sind. Passen Sie die Anzahl der Threads nur an, wenn die Back-End-Ressource ordnungsgemäß optimiert ist.
Auch der Parameter Thread-Zuordnung über die maximale Größe des Thread-Pools hinaus zulassen wirkt sich auf die Größe des Thread-Pools aus. Verwenden Sie diesen Parameter jedoch nur, wenn die Back-End-Ressource über längere Zeiträume hinweg stoppt und damit alle Laufzeitthreads blockiert, die auf das Back-End-System warten, anstatt andere Arbeiten auszuführen, an denen das Back-End-System nicht beteiligt ist.
Sie können die Einstellungen für die Thread-Pool-Größe in der Administrationskonsole anpassen. Klicken Sie auf Server > Servertypen > Anwendungsserver > Servername > Containerservices > ORB-Service > Thread-Pool. Sie können die Mindest- und die Maximalanzahl der Threads anpassen.
Zeitlimit für Thread-Pool
Jede über den Object Request Broker ein- und abgehende Anforderung setzt einen Thread aus dem ORB-Thread-Pool voraus. In Szenarien mit Lastspitzen oder mit tiefen Verschachtelungen von ORB-Anforderungen kann eine Situation entstehen, in der eine Java™ Virtual Machine (JVM) alle Threads aus dem ORB-Thread-Pool beansprucht, die Anforderungen zu senden versuchen. Zeitgleich belegt der ferne JVM-ORB, der diese Anforderungen verarbeitet, alle Threads aus seinem ORB-Thread-Pool, die Anforderungen zu senden versuchen. Infolgedessen gibt es nie einen Fortschritt, Threads werden nicht im ORB-Thread-Pool freigegeben, der ORB kann keine Anforderungen verarbeiten, und es besteht das Risiko, dass ein Deadlock eintritt. In der Administrationskonsole können Sie dieses Verhalten über die angepasste ORB-Eigenschaft "com.ibm.websphere.orb.threadPoolTimeout" anpassen. Weitere Informationen finden Sie im Artikel zu den angepassten Eigenschaften des Object Request Broker.
Fragmentgröße
Der ORB trennt die Nachrichten in Fragmente, die über die ORB-Verbindung gesendet werden. Sie können die Größe dieser Fragmente mit dem Parameter "com.ibm.CORBA.FragmentSize" konfigurieren.
- Aktivieren Sie in der Administrationskonsole auf der Seite "ORB-Eigenschaften" den ORB-Trace.
- Aktivieren Sie auf der Seite "Protokollierung und Tracing" den ORBRas-Trace.
- Erhöhen Sie die Größe für die Tracedateien, da die Menge der beim Erstellen eines Trace generierten Daten sehr hoch sein kann.
- Starten Sie den Server erneut und lösen Sie mindestens eine Operation (vorzugsweise mehrere) des Anwendungsfalls aus, für den Sie die Messung durchführen möchten.
- Suchen Sie dann in der Tracedatei nach Fragment to follow: Yes.
Diese Nachricht weist darauf hin, dass der ORB ein Fragment übertragen hat, aber mindestens noch ein weiteres Fragment zur Vervollständigung der Nachricht gesendet werden muss. Der Wert Fragment to follow: No weist darauf hin, dass das jeweilige Fragment das letzte der gesamten Nachricht ist. Es kann auch das erste Fragment sein, falls die Nachricht in genau ein Fragment passt.
Wenn Sie zu der Stelle mit Fragment to follow: Yes blättern, sehen Sie einen Block wie den folgenden:
Fragment to follow: Yes Message size: 4988 (0x137C) -- Request ID: 1411
Dieses Beispiel gibt an, dass das Fragment 4988 Bytes enthält und die Anforderungs-ID 1411 ist. Wenn Sie jetzt nach allen Vorkommen von Request ID: 1411 suchen, erhalten Sie die Anzahl der Fragmente, die zu dieser Nachricht gehören. Addieren Sie nun die Größen dieser Fragmente, erhalten Sie die Gesamtgröße der Nachricht, die über den ORB gesendet wird.
- Sie können die Fragmentgröße mit der angepassten ORB-Eigenschaft "com.ibm.CORBA.FragmentSize" konfigurieren.
Interceptor
Interceptor sind ORB-Erweiterungen, die den Kontext festlegen können, bevor der ORB eine Anforderung ausführt. Der Kontext kann beispielsweise Transaktionen oder Activity Sessions enthalten, die importiert werden müssen. Wenn der Client eine Transaktion erstellt und den Transaktionskontext an den Server weiterleitet, importiert der Server den Transaktionskontext mit einem Interceptor in die Serveranforderung.
Da die meisten Clients keine Transaktionen oder Activity Sessions starten, empfiehlt es sich auf den meisten Systemen, nicht erforderliche Interceptor zu entfernen.
Zum Entfernen der Interceptor müssen Sie die Datei server.xml editieren und die nicht erforderlichen Interceptor-Zeilen aus dem ORB-Abschnitt entfernen.
Anpassung des Verbindungscache
Sie müssen die Größe des ORB-Verbindungscaches möglicherweise an die Arbeitslast eines Anwendungsservers und die Durchsatz- oder Antwortzeitvoraussetzungen anpassen. Jeder Eintrag im Verbindungscache ist ein Objekt, das einen eindeutigen TCP/IP-Socket-Endpunkt, identifiziert durch den Hostnamen oder die TCP/IP-Adresse, und die Portnummer darstellt, die der ORB verwendet, um eine GIOP-Anforderung oder eine GIOP-Antwort an den fernen Zielendpunkt zu senden. Der Verbindungscache hat den Zweck, die für den Aufbau einer Verbindung benötigte Zeit zu verringern, indem ORB-Verbindungsobjekt für nachfolgende Anforderungen oder Antworten wiederverwendet werden. (Derselbe TCP/IP-Socket wird für die Anforderung und die zugehörige Antwort verwendet.)
Für jeden Anwendungsserver steht die Anzahl der Einträge im Verbindungscache in direktem Zusammenhang mit der Anzahl paralleler ORB-Verbindungen. Diese Verbindungen setzen sich aus den eingehenden Anforderungen von fernen Clients und den abgehenden Anforderungen des Anwendungsservers zusammen. Wenn der ORB auf Serverseite eine Verbindungsanforderung empfängt, verwendet er eine vorhandene Verbindung aus einem Eintrag im Cache oder richtet eine neue Verbindung ein und fügt dem Cache einen Eintrag für diese Verbindung hinzu.
Mit den Eigenschaften für die Maximal- und Mindestgröße des ORB-Verbindungscache können Sie steuern, wie viele Einträge maximal und minimal zu einer Zeit im Verbindungscache enthalten sein dürfen. Wenn die Anzahl der Einträge im Cache den oberen Grenzwert erreicht und eine neue Verbindung erforderlich ist, erstellt der ORB die angeforderte Verbindung, fügt dem Cache einen Eintrag hinzu und sucht nach fünf inaktiven Verbindungseinträgen, die er aus dem Cache löschen kann. Da die neue Verbindung hinzugefügt wird, bevor die inaktiven Einträge entfernt werden, kann die Anzahl der Cacheeinträge vorübergehend den für die Größe des Verbindungscache definierten Maximalwert überschreiten.
Eine ORB-Verbindung wird als inaktiv eingestuft, wenn der TCP/IP-Socket-Datenstrom nicht verwendet wird und keine GIOP-Antworten für Anforderungen in dieser Verbindung anstehen. Wenn sich die Arbeitslast des Anwendungsservers verringert, schließt der ORB die Verbindungen und entfernt die Einträge für diese Verbindungen aus dem Cache. Der ORB löscht so viele Einträge aus dem Cache, bis die Anzahl der verbleibenden Einträge kleiner-gleich dem für die Größe des Verbindungscache definierten Maximalwert ist. Die Anzahl der Cacheeinträge unterschreitet nie den für die Mindestgröße des Verbindungscache definierten Wert, der mindestes fünf Verbindungen kleiner sein muss als der Wert, der für den Maximalwert definiert wird.
Normalerweise sind keine Anpassungen am Verbindungscache im ORB auf Clientseite erforderlich, weil nur eine kleine Anzahl von Verbindungen auf dieser Seite erstellt wird.
JNI-Reader-Threads
Standardmäßig verwendet der ORB einen Java-Thread für die Verarbeitung jeder eingehenden Verbindungsanforderung, die er empfängt. Bei steigender Anzahl paralleler Anforderungen nimmt der Speicherbedarf durch die Reader-Threads zu, was in Umgebung mit begrenzten Ressourcen zu einem Engpass führen kann. Die Anzahl der erstellten Java-Threads kann schließlich Ausnahmen aufgrund mangelnden Speichers auslösen, wenn die Anzahl paralleler Anforderungen die verfügbaren Ressourcen des Systems übersteigt.
Zur Vermeidung dieses potenziellen Problems können Sie den ORB so konfigurieren, dass er JNI-Reader-Threads verwendet, für die eine begrenzte Anzahl von Reader-Threads, die mit nativen Betriebssystem-Threads anstelle von Java-Threads implementiert werden, während der Initialisierung des ORB erstellt wird. JNI-Reader-Threads basieren auf dem nativen TCP/IP-Mechanismus des Betriebssystems für asynchrone Verarbeitung, der einem einzelnen nativen Betriebssystemthread die Verarbeitung von E/A-Ereignissen mehrerer Sockets gleichzeitig ermöglicht. Der ORB verwaltet die Verwendung der JNI-Reader-Threads und ordnet mit einem Round-Robin-Algorithmus einen der verfügbaren Threads für die Verarbeitung der Verbindungsanforderung zu. Normalerweise sollten JNI-Reader-Threads nur konfiguriert werden, wenn die Verwendung von Java-Threads zu speicherintensiv für Ihre Anwendungsumgebung ist.
- Da eine feste Anzahl von Threads reserviert wird, verringert sich der Speicherbedarf. Dies kann in Umgebungen mit einer hohen und konstanten Anzahl von Clientanforderungen einen erheblichen Vorteil bringen.
- Die erforderliche Zeit für das dynamische Erstellen und Löschen von Java-Threads fällt weg, weil eine feste Anzahl von JNI-Threads während der Initialisierung des ORB erstellt und reserviert wird.
- Jeder JNI-Thread kann bis zu 1024 Socket-Verbindungen verarbeiten und interagiert direkt mit dem nativen Betriebssystemmechanismus für asynchrone E/A-Verarbeitung. Dies kann zu einer höheren Leistung bei der E/A-Verarbeitung im Netz führen.