web-dev-qa-db-fra.com

Comment faire dialoguer 2 JVM

J'ai la situation suivante:

J'ai 2 processus JVM (vraiment 2 Java processus fonctionnant séparément, pas 2 threads) fonctionnant sur une machine locale. Appelons-les ProcessA an ProcessB.

Je veux qu'ils communiquent (échangent des données) entre eux (par exemple ProcessA envoie un message à ProcessB pour faire quelque chose).

Maintenant, je contourne ce problème en écrivant un fichier temporaire et ces processus analysent régulièrement ce fichier pour obtenir un message. Je pense que cette solution n'est pas si bonne.

Quelle serait une meilleure alternative pour réaliser ce que je veux?

62
tnk_peka

Plusieurs options pour IPC :

Réseaux basés sur des sockets (Bare-Bones)

  • pas nécessairement difficile , mais:
    • pourrait être verbeux pour pas grand-chose,
    • peut offrir plus de surface pour les bogues, lorsque vous écrivez plus de code.
  • vous pouvez vous fier aux frameworks existants, comme Netty

RMI

  • Techniquement, c'est aussi une communication réseau, mais c'est transparent pour vous.

Architectures de passage de messages à part entière

  • généralement basé sur RMI ou les communications réseau, mais avec prise en charge des conversations et des workflows compliqués
  • pourrait être trop lourd pour quelque chose de simple
  • des frameworks comme ActiveMQ ou JBoss Messaging

Java Management Extensions (JMX)

  • plus destiné à gestion et surveillance de la JVM , mais pourrait aider à implémenter ce que vous voulez si vous voulez surtout qu'un processus interroge un autre pour les données, ou lui envoie une demande d'action, si ce n'est pas le cas trop compliqué
  • fonctionne également sur RMI (parmi d'autres protocoles possibles)
  • pas si simple d'enrouler la tête au début, mais en fait assez simple à utiliser

Partage de fichiers/verrouillage de fichiers

  • c'est ce que tu fais en ce moment
  • c'est faisable, mais vient avec beaucoup de problèmes à gérer

Signaux

  • Vous pouvez simplement envoyer des signaux à votre autre projet
  • Cependant, il est assez limité et vous oblige à implémenter une couche de traduction (il est faisable, cependant, mais une idée assez folle pour jouer avec quoi que ce soit de sérieux).

Sans plus de détails, une approche réseau à nu IPC semble la meilleure, car c'est la:

  • plus extensible (en termes d’ajout de nouvelles fonctionnalités et de nouveaux workflows à votre
  • le plus léger (en termes d'encombrement mémoire pour votre application)
  • le plus simple (en termes de conception)
  • le plus éducatif (en termes d'apprentissage de la mise en œuvre de la CIB). (comme vous l'avez mentionné "socket est difficile" dans un commentaire, et ce n'est vraiment pas et devrait être quelque chose sur lequel vous travaillez)

Cela étant dit, sur la base de votre exemple (simplement demander à l'autre processus de faire une action), JMX pourrait également être assez bon pour vous.

79
haylem

J'ai ajouté une bibliothèque sur github appelée Mappedbus ( http://github.com/caplogic/mappedbus ) qui permet deux (ou beaucoup plus) Java processus/JVM pour communiquer en échangeant des messages. La bibliothèque utilise un fichier mappé en mémoire et utilise des fonctions de lecture-écriture et de lecture/écriture volatiles pour synchroniser les différents lecteurs et écrivains. J'ai mesuré le débit entre deux processus utilisant cette bibliothèque à 40 millions de messages/s avec une latence moyenne de 25 ns pour lire/écrire un seul message.

18
MikaelJ

Ce que vous recherchez est inter-process communication. Java fournit un cadre simple IPC sous la forme Java RMI API . Il existe plusieurs autres mécanismes de communication inter-processus tels que comme des tuyaux, des sockets, des files d'attente de messages (ce sont tous des concepts, évidemment, donc il y a des cadres qui les implémentent).

Je pense que dans votre cas Java RMI ou une simple implémentation de socket personnalisé devrait suffire.

6
Strelok

Sockets avec DataInput (Output) Stream, pour envoyer des objets Java dans les deux sens. C'est plus facile que d'utiliser un fichier disque, et beaucoup plus facile que Netty.

3

J'ai tendance à utiliser jGroup pour former des grappes locales entre les processus. Il fonctionne pour les nœuds (ou processus) sur la même machine, au sein de la même machine virtuelle Java ou même sur différents serveurs.

Une fois que vous comprenez les bases, il est facile de travailler avec et d'avoir les options pour exécuter réellement deux processus ou plus dans la même JVM, il est facile de tester ces processus facilement.

La surcharge et la latence sont minimes si les deux sont sur la même machine (généralement seulement un TCP rountrip d'environ> 100 ns par action).

2
Martin Kersten

la prise peut être un meilleur choix, je pense.

1
Marcus

En 2004, j'implémente du code qui fait le travail avec les sockets. D'ici là, je recherche souvent une meilleure solution, car l'approche socket déclenche le pare-feu et mes clients s'inquiètent. Il n'y a pas de meilleure solution jusqu'à présent. Le client doit sérialiser vos données, envoyer et le serveur doit recevoir et désérialiser. C'est facile.

0
Chameleon