Normalerweise wird es dem Betriebssystem überlassen, zu entscheiden, welche Prozessoren oder Prozessorkerne der Maschine genutzt werden, um eine Anwendung auszuführen. Abhängig von der Zahl der Threads, die von einer Anwendung zu einer bestimmten Zeit genutzt werden, und den Anforderungen anderer Anwendungen, wird das Betriebssystem versuchen, Threads so häufig wie notwendig herumzuverteilen, um die Gesamtlast auf jeden Prozessor ausgeglichen zu halten. Wenn es mehr Threads als Prozessoren gibt (was der Normalfall ist), wird das Betriebssystem Prozessoren unter mehreren Threads verteilen, das bedeutet, dass Threads warten müssen bis sie an der Reihe sind. Für ein paar Anwendungen wird diese Methode nicht ausreichend sein, und es kann nützlich sein, bestimmte Prozessoren oder Gruppe von Prozessoren für bestimmte Anwendungen zu reservieren. Die meisten Betriebssystemplattformen bieten die Fähigkeit an, festzulegen, dass ein Prozess nur auf spezifischen Prozessoren ausgeführt werden soll. Dies wird gewöhnlich mit CPU-Affinity oder CPU-Pinning bezeichnet.

Das Zuweisen von spezifischen Prozessoren zu Ihrer Anwendung kann eine Möglichkeit sein, sicherzustellen, dass stets genügend Prozessorressourcen verfügbar sind. Im Gegenteil sollten Sie explizit einige Prozessoren ungenutzt lassen, um sicherzustellen, dass genügend Ressourcen für andere Prozesse die auf der gleichen Maschine laufen, zur Verfügung stehen. Festlegen der CPU-Affinity kann auch wesentlich zur Optimierung des CPU-Caches beitragen. In anderen Worten, wann immer ein Prozess den Prozessor verändert, werden dessen Daten von einem Prozessor zu einem anderen Prozessor übertragen. Diese Übertragung ist kostenintensiv, aber Sie können dies durch Bindung des Prozesses an eine beschränkte Anzahl von Prozessoren minimieren. Sie sollten jedoch umsichtig vorgehen, für Ihre Anwendung genügend Prozessoren zulassen, da diese die Fähigkeit haben mag, Tasks parallel auf verschiedenen Prozessoren, sofern verfügbar, auszuführen.

Unglücklicherweise stellt Java nicht die Möglichkeit zur Verfügung, die JVM mit Core- oder Processor-Affinity zu starten. Sollten Sie Interesse haben, Ihre Java-Anwendung an spezifische Prozessoren zu binden, würden Sie entweder Befehle wie procaff, taskset oder invoke native code benutzen. Processor affinity Diese Lösungen sind plattformspezifisch.

Lösung

Die Java Service Wrapper Professional Edition behandelt dieses Problem, indem diese einen einheitlichen und einfachen Weg anbietet, um CPU-Affinity zu konfigurieren - ohne Programmieraufwand. Laut Version 3.5.27 werden nur Windows und Linux unterstützt, aber zusätzliche Plattformunterstützung ist in naher Zukunft geplant.

Die Konfiguration kann sich auf den Wrapper-Prozess wie auf den von ihm kontrollierten JVM-Prozess beziehen. Jeder hat seine eigenen Eigenschaften, um Prozessor-Affinität zu konfigurieren. Aber wenn Sie nur die des Wrappers bestimmen, wird der überwachte JVM-Prozess standardmäßig die gleiche Konfiguration erben und automatisch unter Nutzung der gleichen Prozessoren wie der Wrapper-Prozess ausgeführt.

Technische Übersicht

Wie CPU-Affinity für den Wrapper konfiguriert wird

Kompatibel :3.5.27
Editionen :Professional EditionStandard Edition (Not Supported)Community Edition (Not Supported)
Betriebssysteme :WindowsMac OSX (Not Supported)LinuxIBM AIX (Not Supported)FreeBSD (Not Supported)HP-UX (Not Supported)Solaris (Not Supported)IBM z/OS (Not Supported)IBM z/Linux

Die Eigenschaften, die benutzt werden, um CPU-Affinity für den Wrapper-Prozess zu konfigurieren, sind unten beschrieben:

Zum Beispiel, wenn Sie möchten, dass der Wrapper nur auf den Prozessoren 1 und 2 laufen soll, können Sie die folgende Reihe an Eigenschaften in Ihre Konfigurationsdatei (wrapper.conf) schreiben:

Beispiel
wrapper.cpu_affinity.set=TRUE
wrapper.cpu_affinity.default=FALSE
wrapper.cpu_affinity.1=TRUE
wrapper.cpu_affinity.2=TRUE

Im gegenteiligen Fall, wenn Sie möchten, dass der Wrapper auf allen Prozessoren mit Ausnahme der Prozessoren 1 und 2 laufen soll, können Sie wie folgt schreiben:

Beispiel
wrapper.cpu_affinity.set=TRUE
wrapper.cpu_affinity.default=TRUE
wrapper.cpu_affinity.1=FALSE
wrapper.cpu_affinity.2=FALSE

Wie CPU-Affinity für den JVM-Prozess konfiguriert wird

Kompatibel :3.5.27
Editionen :Professional EditionStandard Edition (Not Supported)Community Edition (Not Supported)
Betriebssysteme :WindowsMac OSX (Not Supported)LinuxIBM AIX (Not Supported)FreeBSD (Not Supported)HP-UX (Not Supported)Solaris (Not Supported)IBM z/OS (Not Supported)IBM z/Linux

Die vorherigen Beispiele sollten in den meisten Fällen genügen, da Ihre Java-Anwendung und alle Ihre Kindprozesse und Threads automatisch die gleiche Konfiguration erben und auf den gleichen Prozessoren laufen. Wenn Sie jedoch eine unterschiedliche CPU-Affinity-Konfiguration für den Wrapper und seinen kontrollierten Prozess spezifizieren wollen, ist dies möglich, indem Sie die folgende Reihe an Eigenschaften benutzen.

Sie können diese Eigenschaften auf die gleiche Art nutzen, wie zuvor angezeigt.

Beispiel 1 (erlaubt der JVM nur auf den Prozessoren Nummer 1 und 2 ausgeführt zu werden)
wrapper.cpu_affinity.set=TRUE
wrapper.java.cpu_affinity.default=FALSE
wrapper.java.cpu_affinity.1=TRUE
wrapper.java.cpu_affinity.2=TRUE
Beispiel 2 (erlaubt der JVM auf allen Prozessoren zu laufen, mit Ausnahme des Prozessors Nummer 1 und 2)
wrapper.cpu_affinity.set=TRUE
wrapper.java.cpu_affinity.default=TRUE
wrapper.java.cpu_affinity.1=FALSE
wrapper.java.cpu_affinity.2=FALSE

Überprüfen Sie, dass CPU-Affinity funktioniert

Im vorherigen Beispiel haben Sie bemerkt, dass der erste Prozessor mit Index 1 bezeichnet, der zweite Prozessor mit Index 2 und so fort bezeichnet wurde. Wenn Sie die Prozessorauslastung Ihres Systems prüfen, wird der erste Prozessor manchmal mit Index 0 und ein anderes Mal mit Index 1 bezeichnet. Wenn Sie den Wrapper konfigurieren, wird der erste Prozessor stets mit Index 1 bezeichnet.

Um unter Windows die Prozessorauslastung angezeigt zu bekommen, öffnen Sie den Task Manager, wählen Sie die Registerkarte Performance, machen dann einen Rechtsklick auf die Hauptleiste und wählen im Kontextmenü Change Graph zu Logical processors. Wenn Sie Ihre Anwendung so konfiguriert haben, nur auf Prozessor 1 und 2 zu laufen, sollten Sie etwas wie folgt sehen:


Auslastung der Prozessoren unter Windows (Task Manager)

Um die Prozessor-Auslastung unter Linux zu sehen, können Sie den top Befehl in Ihrem Terminal nutzen und dann auf 1 drücken, um Details bezüglich den logischen Prozessoren angezeigt zu bekommen.

Auf Ubuntu können Sie den System Monitor öffnen, wenn Sie es bevorzugen, die Prozessoren-Auslastung in einem GUI-Fenster angezeigt zu bekommen:


Prozessorenauslastung unter Ubuntu (System Monitor)