
Ich arbeite auf einem Server, der Vert.x in Java verwendet, und mir sind einige Leistungsprobleme aufgefallen, wenn ich die Anwendung auf einem dedizierten Server mit Ubuntu 12.04 ausführe.
Der Server nimmt die eingehenden HTTP-Anfragen entgegen, führt mithilfe von HMACs eine Authentifizierung durch, analysiert die Anfragetexte, führt einige Textverarbeitungen durch und sendet Daten über UDP an einen anderen Server. Es gibt keinen Festplatten-E/A und nur eine relativ geringe Speichernutzung (bei weitem nicht im Bereich des Swap-Speichers). Ich führe Lasttests mit dem Server mithilfe von Grinder- und AWS-Instanzen durch, aber selbst mit einem gut ausgestatteten Server kann ich nicht mehr als 10.000 Anfragen pro Sekunde erhalten.
Was ich sehe, ist, dass ein Kern auf dem Server-Rechner absolut ausgelastet ist, hauptsächlich im Kernel, und die anderen Kerne nur zu etwa 20–25 % ausgelastet sind. Ich gehe davon aus, dass die CPU für den Empfang eingehender TCP-Verbindungen verwendet wird. JMX meldet die meiste Zeit in io.netty.channel.nio.NioEventLoop.select(), was meiner Meinung nach die Wartezeit auf den Kernel zählt, und strace zeigt viel Zeit in futex() und epoll_wait() an. Ich habe versucht, mit den Kernel-Einstellungen herumzuspielen, um den Durchsatz des Servers zu erhöhen, aber ich hatte kein Glück.
Profiler-Lauf:
ursprüngliche URL:https://i.stack.imgur.com/6wIZA.png
CPU auslastung:
ursprüngliche URL:https://i.stack.imgur.com/9mM5u.png
Ich frage mich, was man auf Kernelebene anpassen kann, um das zu beheben. Ich habe versucht, die TCP-Puffergrößen zu ändern, Dateihandles zu erhöhen, TCP-Funktionen auszuschalten usw., aber ohne Erfolg. Dieses Server-Betriebssystem läuft tatsächlich auf Xen, es ist „dediziert“, da es das einzige residente Betriebssystem ist.
Antwort1
Ich würde Ihre Anwendung und die von ihr verwendeten Bibliotheken genau prüfen. Was den Linux-Kernel betrifft, werden JVM-Threads unter Linux als native Threads (leichtgewichtige Prozesse) implementiert, zumindest bei der JVM-Implementierung von Sun/Oracle.
Die JVM ist ein einzelner Prozess mit vielen Threads. Jeder Thread, den sie startet, kann auf jedem verfügbaren Kern ausgeführt werden. Ein einzelner Prozess in Linux kann viele Threads haben.
Vielleicht möchten Sie auch einen Blick auf diese Ressourcen werfen: