Wie man 2 JVMs miteinander spricht

71

Ich habe folgende Situation:

Ich habe 2 JVM-Prozesse (wirklich 2 javaProzesse, die separat ausgeführt werden, nicht 2 Threads), die auf einem lokalen Computer ausgeführt werden. Nennen wir sie ProcessAeine ProcessB.

Ich möchte, dass sie miteinander kommunizieren (Daten austauschen) (z. B. ProcessAeine Nachricht senden ProcessB, um etwas zu tun).

Jetzt umgehe ich dieses Problem, indem ich eine temporäre Datei schreibe. Diese Prozesse scannen diese Datei regelmäßig, um eine Nachricht zu erhalten. Ich denke, diese Lösung ist nicht so gut.

Was wäre eine bessere Alternative, um das zu erreichen, was ich will?

tnk_peka
quelle
In der Zwischenzeit wurden den möglichen Ansätzen Speicherzuordnungsdateien hinzugefügt.
Nikolai Dmitriev

Antworten:

85

Mehrere Optionen für IPC :

Socket-basiertes Netzwerk (Bare-Bones)

  • nicht unbedingt schwer , aber:
    • könnte für nicht viel wortreich sein,
    • bietet möglicherweise mehr Oberfläche für Fehler, wenn Sie mehr Code schreiben.
  • Sie können sich auf vorhandene Frameworks wie Netty verlassen

RMI

  • Technisch gesehen ist das auch Netzwerkkommunikation, aber das ist für Sie transparent.

Vollwertige Message-Passing-Architekturen

  • Normalerweise basiert es entweder auf RMI- oder Netzwerkkommunikation, unterstützt jedoch komplizierte Konversationen und Workflows
  • könnte für etwas Einfaches zu schwer sein
  • Frameworks wie ActiveMQ oder JBoss Messaging

Java Management Extensions (JMX)

  • Dies ist eher für die Verwaltung und Überwachung von JVM gedacht , kann jedoch dazu beitragen, das zu implementieren, was Sie möchten, wenn ein Prozess meistens einen anderen nach Daten abfragen soll, oder eine Anforderung für eine Aktion senden, wenn diese nicht zu komplex sind
  • funktioniert auch über RMI (unter anderen möglichen Protokollen)
  • Zunächst nicht so einfach, den Kopf herumzuwickeln, aber eigentlich eher einfach zu bedienen

Filesharing / Dateisperrung

  • Das ist es, was du gerade machst
  • Es ist machbar, bringt aber viele Probleme mit sich

Signale

  • Sie können einfach Signale an Ihr anderes Projekt senden
  • Es ist jedoch ziemlich begrenzt und erfordert die Implementierung einer Übersetzungsebene (es ist zwar machbar, aber eine ziemlich verrückte Idee, mit der man spielen kann, als irgendetwas Ernstes.

Ohne weitere Details scheint ein netzwerkbasierter IPC-Ansatz am besten zu sein, da er:

  • am erweiterbarsten (in Bezug auf das Hinzufügen neuer Funktionen und Workflows zu Ihrem
  • am leichtesten (in Bezug auf den Speicherbedarf für Ihre App)
  • am einfachsten (in Bezug auf das Design)
  • am lehrreichsten (in Bezug auf das Erlernen der Implementierung von IPC). (Wie Sie in einem Kommentar erwähnt haben, ist "Socket ist hart", und es ist wirklich nicht und sollte etwas sein, an dem Sie arbeiten.)

Basierend auf Ihrem Beispiel (indem Sie einfach den anderen Prozess auffordern, eine Aktion auszuführen) könnte JMX auch gut genug für Sie sein.

Haylem
quelle
Beachten Sie, dass JMX Probleme beim Umgang mit mehreren Klassenladeprogrammen hat, wenn Objekte in der JVM gemeinsam genutzt werden. Casting ist problematisch. Möglicherweise ist manchmal eine Serialisierung / Deserialisierung erforderlich.
LppEdd
20

Ich habe auf github eine Bibliothek namens Mappedbus ( http://github.com/caplogic/mappedbus ) hinzugefügt, die es zwei (oder vielen weiteren) Java-Prozessen / JVMs ermöglicht, durch Austausch von Nachrichten zu kommunizieren. Die Bibliothek verwendet eine Speicherzuordnungsdatei und verwendet Abrufen und Hinzufügen sowie flüchtiges Lesen / Schreiben, um die verschiedenen Leser und Schreiber zu synchronisieren. Ich habe den Durchsatz zwischen zwei Prozessen mit dieser Bibliothek auf 40 Millionen Nachrichten / s mit einer durchschnittlichen Latenz von 25 ns zum Lesen / Schreiben einer einzelnen Nachricht gemessen.

MikaelJ
quelle
5
Wenn ich mich nicht irre, ordnet diese Bibliothek eine Datei mit fester Größe dem Speicher zu und hängt Nachrichten an, bis das Dateiende erreicht ist. Bedeutet das, dass sie einfach stirbt, wenn alles aus der Datei gelesen wird? Es ist kein Ringpuffer, soweit ich das
beurteilen
7

Was Sie suchen, ist inter-process communication. Java bietet ein einfaches IPC-Framework in Form der Java RMI API . Es gibt verschiedene andere Mechanismen für die Kommunikation zwischen Prozessen, wie z. B. Pipes, Sockets und Nachrichtenwarteschlangen (dies sind natürlich alle Konzepte, daher gibt es Frameworks, die diese implementieren).

Ich denke in Ihrem Fall sollte Java RMI oder eine einfache benutzerdefinierte Socket-Implementierung ausreichen.

Strelok
quelle
1
Wie bei Rohren (benannte Rohre). Dies ist der einfachste Weg, da Sie nur normale Dateien lesen / schreiben.
Dmitry Trifonov
@DmitryTrifonov Pipes funktionieren nur für zwei Threads, die in derselben JVM ausgeführt werden. Diese Frage wurde speziell für zwei verschiedene Prozesse gestellt.
Ignace Vau
@IgnaceVau könnten Sie auf Rohre erweitern? Ich würde gerne mehr verstehen (Beispiele, Dokumentation). Vielen Dank!
LppEdd
3

Sockets mit DataInput (Output) Stream zum Senden von Java-Objekten hin und her. Dies ist einfacher als die Verwendung einer Festplattendatei und viel einfacher als Netty.

Alexei Kaigorodov
quelle
2

Ich benutze jGroup, um lokale Cluster zwischen Prozessen zu bilden. Es funktioniert für Knoten (auch als Prozesse bezeichnet) auf demselben Computer, innerhalb derselben JVM oder sogar auf verschiedenen Servern.

Sobald Sie die Grundlagen verstanden haben, ist es einfach, damit zu arbeiten, und die Optionen, zwei oder mehr Prozesse in derselben JVM auszuführen, machen es einfach, diese Prozesse einfach zu testen.

Der Overhead und die Latenz sind minimal, wenn sich beide auf demselben Computer befinden (normalerweise nur eine TCP-Rountrip von ca.> 100 ns pro Aktion).

Martin Kersten
quelle
1

Steckdose ist vielleicht die bessere Wahl, denke ich.

Marcus
quelle
Socket ist schwer zu implementieren, daher denke ich nicht, dass es ein einfacher Weg ist. Gibt es eine andere Lösung? Eine übergeordnete API, ein Framework, das einfacher zu implementieren ist.
tnk_peka
1
Schwer oder einfach hängt vom Zweck ab. Für eine einfache Sache glaube ich NICHT, dass die Verwendung der schweren Bibliotheken mehr wert ist, als einfach eine Socket-Klasse selbst zu erstellen.
MD
0

Im Jahr 2004 implementiere ich Code, der die Arbeit mit Sockets erledigt. Bis dahin suche ich oft nach einer besseren Lösung, weil der Socket-Ansatz eine Firewall auslöst und meine Kunden sich Sorgen machen. Bisher gibt es keine bessere Lösung. Der Client muss Ihre Daten serialisieren, senden und der Server muss empfangen und unserialisieren. Es ist leicht.

Chamäleon
quelle