Java TCP/IP Socket-Performance Problem
Unserer Anwendung ist das Lesen von Daten sehr schnell über TCP/IP-sockets in Java. Wir sind mit der NIO-Bibliothek mit einer non-blocking-Sockets und einen Selektor, um anzuzeigen, Bereitschaft zu Lesen. Im Durchschnitt der gesamten Bearbeitungszeit für die Lektüre und Verarbeitung der gelesenen Daten werden im sub-Millisekundenbereich.
Allerdings haben wir Häufig sehen, Spitzen von 10-20 Millisekunden. (läuft auf Linux).
Mit tcpdump wir können sehen, dass die Zeitdifferenz zwischen tcpdump ist das Lesen von 2 diskrete Nachrichten, und vergleichen Sie mit unseren Anwendungen Zeit. Wir sehen tcpdump zu haben scheint, keine Verzögerung, in der Erwägung, dass die Anwendung zeigen können 20 Millisekunden.
Wir sind ziemlich sicher, dass dies nicht GC, denn die GC-log zeigt nahezu keine Full GC und in JDK 6 (von dem was ich verstehe) die Standard-GC-parallel ist, so sollte es nicht anhalten, die Anwendungs-threads (es sei denn Full GC).
Es beinahe so aussieht, als wenn es eine Verzögerung für Java Selector.select(0)
Methode zum zurückgeben der Bereitschaft zu Lesen, da der TCP-Schicht, die Daten sind bereits verfügbar, gelesen zu werden (und tcpdump ist es zu Lesen).
Zusätzliche Info: bei Spitzenlast arbeiten wir rund 6.000 x 150 avg bytes pro Nachricht, oder über 900 MB pro Sekunde.
- Wie @Jim Lewis, sagte, es wird wahrscheinlich noch einige Zeit-der Verlust an Kontext-switching, und Sie können nicht Steuern, wie Java implementiert NIO intern. Es ist durchaus möglich, dass die JVM fügt einige zusätzlichen Aufwand, den Sie nicht beseitigen können. Das heißt, ohne zu sehen, mehr Daten kann ich nicht wirklich eine Lösung bieten.
- Gut - ich räumte meinen abgelehnten Antworten. Ich möchte nicht, dass jemand zu denken, dass ich keinen Wert auf die Zeit, die Sie nahm, um die Frage zu beantworten.
- Ich könnte helfen, geben einige details über jvm kernel/Distribution, hardware
- O/S=Linux Red Hat Enterprise 5.4, Kernel-version=2.6, JVM=Java(TM) SE Runtime Environment (build 1.6.0_06-b02) Java HotSpot(TM) Server VM (build 10.0-b22, gemischter Modus), NIC: NIC: 01:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20), Netzwerk-Geschwindigkeit=1 Gbit / s Full Duplex.
- die Infos sollten in deiner Frage.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kollektion eden noch gegen STW pause also 20ms kann völlig normal-je nach Zuordnung-Verhalten & heap-Größe/Größe der live-set.
Ist dein Java-code läuft unter RTLinux, oder eine andere Distribution mit hard real-time scheduling-Funktion? Wenn nicht, 10-20 MS jitter in der Bearbeitung mal scheint völlig vernünftig, und erwarten.
Ich hatte das gleiche problem in einem java-service, dass ich die Arbeit auf. Beim versenden der gleichen Anfrage
immer wieder aus der client den server blockieren würde an der gleichen Stelle im Datenstrom für 25-35ms.
Deaktivieren des Nagle-Algorithmus in der Buchse fest für mich.
Dies kann erreicht werden durch Aufruf von setTcpNoDelay(true) auf den Sockel.
Dies kann dazu führen, erhöhte Netzwerk-Staus, weil ACKs wird jetzt gesendet werden als separate
- Pakete.
Sehen http://en.wikipedia.org/wiki/Nagle%27s_algorithm für mehr info auf den Nagle-Algorithmus.
Aus der tcpdump-faq:
Also Verschiedenheit, der timestamp wird in den privilegierten kernel-Ebene, und die verlorenen 20ms ist context-switching-overhead zurück in den user-space und in Java und der JVM-Netzwerk-Selektor Logik. Ohne weitere Analyse des Systems als ganzes ich denke nicht, dass es möglich ist, eine positive Auswahl der Ursache.