Communication entre les JVM locales

ma question: quelle approche pourrais-je/devrais-je adopter pour communiquer entre deux ou plusieurs instances JVM qui fonctionnent localement?

une description du problème:

Je suis en train de développer un système pour un projet qui nécessite des instances JVM distinctes pour isoler complètement certaines tâches les unes des autres.

dans son exécution, la JVM "mère" créera des JVM "enfants" qu'elle s'attendra à exécuter, puis lui retournera les résultats (en le format des classes POJO relativement simples, ou peut-être des données XML structurées). Ces résultats ne doivent pas être transférés en utilisant les pipes SysErr/SysOut/SysIn car l'enfant peut déjà les utiliser dans le cadre de son fonctionnement.

si un JVM enfant ne répond pas avec des résultats dans un certain délai, le JVM parent devrait être en mesure de signaler à l'enfant de cesser le traitement, ou de tuer le processus enfant. Dans le cas contraire, l'entreprise commune enfant devrait sortir normalement à la fin de la réalisation de son projet. tâche.

Recherche:

Je suis conscient qu'il existe un certain nombre de technologies qui peuvent être utiles, par exemple:...

  • utilisation de la bibliothèque RMI de Java
  • utilisation de sockets pour transférer des objets
  • en utilisant des bibliothèques de distribution telles que Cajo, Hessian

...mais je suis intéressé à entendre quelles approches les autres peuvent envisager avant de poursuivre l'une de ces options, ou d'autres.

Merci pour tout de l'aide ou des conseils sur ce!

Modifications:

Quantité de données à transférer- relativement petit, il ne sera généralement qu'une poignée de POJOs contenant des cordes qui représenteront le résultat de l'exécution de l'enfant. Si aucune solution serait inefficace sur de plus grandes quantités d'informations, c'est peu probable problème dans mon système. La quantité transférée devrait être assez statique et donc cela fait être évolutif.

latence of transfer - pas une préoccupation critique dans ce cas, bien que si un "sondage" des résultats est nécessaire, cela devrait pouvoir être assez fréquent sans frais généraux significatifs, de sorte que je puisse maintenir une interface graphique réactive en plus de cela à un moment ultérieur (par ex. barre de progression)

24
demandé sur obfuscation 2011-02-19 19:48:45
la source

11 ответов

j'utilise KryoNet avec des sockets locaux car il est très spécialisé dans la sérialisation et est assez léger (vous obtenez aussi L'Invocation de méthode À Distance! Je l'utilise en ce moment), mais désactivez le délai de déconnexion de la prise.

RMI fonctionne essentiellement sur le principe que vous avez un type distant et que le type distant implémente une interface. Cette interface est partagée. Sur votre machine locale, vous liez l'interface via la bibliothèque RMI au code "injecté" en mémoire de la bibliothèque RMI, le résultat est que vous avez quelque chose qui satisfait l'interface mais qui est capable de communiquer avec l'objet distant.

5
répondu Chris Dennett 2011-02-19 21:03:17
la source

pas directement une réponse à votre question, mais une suggestion d'alternative. Avez-vous envisagé d' OSGI?

il vous permet d'exécuter des projets java complètement isolés les uns des autres, au sein de la même jvm. La beauté de cela est que la communication entre les projets est très facile avec les services (voir spécifications de base PDF page 123). De cette façon, il n'y a pas de "sérialisation" de quelque sorte fait que les données et les appels sont tous dans le même jvm.

en outre toutes vos exigences de qualité de service (temps de réponse etc...) d'aller plus loin - vous que vous avez seulement à vous soucier de savoir si le service est HAUT ou vers le BAS au moment où vous souhaitez l'utiliser. Et pour cela vous avez une spécification vraiment agréable qui fait cela pour vous appelé des Services déclaratifs (voir Enterprise Spec PDF page 141)

Désolé pour la réponse hors sujet, mais j'ai pensé que certains d'autres personnes pourraient considérer cela comme une alternative.

mise à Jour

pour répondre à votre question sur la sécurité, je n'ai jamais envisagé un tel scénario. Je ne crois pas qu'il y ait un moyen d'imposer L'usage de la "mémoire" au sein D'OSGI.

Enterprise Spec PDF

akka est une autre option, ainsi que autres java acteur cadres, il fournit la communication et d'autres goodies dérivés de la modèle d'acteur.

5
répondu superfav 2011-02-20 00:12:07
la source

si vous ne pouvez pas utiliser stdin / stdout, alors j'utiliserais des douilles. Vous avez besoin d'une sorte de couche de sérialisation sur le dessus des sockets (comme vous le feriez avec stdin/stdout), et RMI est une couche très facile à utiliser et assez efficace.

si vous avez utilisé RMI et trouvé que la performance n'était pas assez bonne, je passerais à un serialiseur plus efficace - Il ya beaucoup d'options.

Je n'irais nulle part près des services web ou XML. Cela me semble un gâchis complet il faut probablement plus d'efforts et moins de rendement que L'IGR.

4
répondu Tom Anderson 2011-02-19 20:59:59
la source

peu de gens semblent aimer RMI plus longtemps.

Options:

  1. Web Services. par exemple http://cxf.apache.org
  2. JMX. Maintenant, c'est vraiment un moyen d'utiliser RMI sous la table, mais ça marcherait.
  3. autres protocoles IPC; vous avez cité Hessian
  4. roulez vous-même en utilisant des sockets, ou même de la mémoire partagée. (Ouvrir un fichier mappé dans le parent, l'ouvrir à nouveau à l'enfant. Il te faudrait quand même quelque chose pour synchronisation.)

des exemples notables sont Apache ant (qui bifurque toutes sortes de JVM pour un usage ou un autre), Apache maven, et la variante open source du kit de démonisation Tanukisoft.

personnellement, je suis très facile avec les services web, donc c'est le marteau que j'ai tendance à transformer les choses en clous. Un service typique JAX-WS+JAX-B ou JAX-RS+JAX-B est très peu de code avec CXF, et gère toutes les sérialisations de données et la deserialisation pour moi.

3
répondu bmargulies 2011-02-19 23:08:44
la source

il a été mentionné ci-dessus, mais je voulais développer un peu sur la suggestion de JMX. nous faisons en fait à peu près exactement ce que vous prévoyez de faire (d'après ce que je peux glaner à partir de vos divers commentaires). nous avons atterri en utilisant jmx pour une variété de raisons, dont quelques-unes que je vais mentionner ici. tout d'abord, jmx est une affaire de gestion, donc en général, c'est une solution parfaite pour ce que vous voulez faire (surtout si vous prévoyez déjà d'avoir des services jmx pour d'autres tâches de gestion). tout l'effort que vous mettez dans les interfaces jmx fera double fonction comme apis que vous pouvez appeler en utilisant des outils de gestion java comme jvisualvm. ceci m'amène au point suivant, qui est le plus pertinent à ce que vous voulez. la nouvelle Attach APIcelui-ci, ce qui montre comment utiliser l'api attach dynamiquement dans votre propre programme.

3
répondu jtahlborn 2012-08-03 06:14:56
la source

bien qu'il soit conçu pour une communication potentiellement à distance entre les JVM, je pense que vous trouverez que Netty fonctionne aussi très bien entre les instances JVM locales.

c'est probablement la bibliothèque la plus performante / Robuste / largement supportée de son type pour Java.

2
répondu mikera 2011-02-19 21:12:30
la source

beaucoup de choses sont discutées ci-dessus. Mais qu'il s'agisse de sockets, rmi, jms - il y a beaucoup de travail sale en jeu. Je ratter conseils akka. C'est un modèle basé sur les acteurs qui communiquent entre eux en utilisant des Messages.

la beauté est que les acteurs peuvent être sur le même JVM ou un autre (très peu de config) et akka s'occupe du reste pour vous. Je n'ai pas vu une version plus propre façon de le faire :)

2
répondu Jatin 2013-05-09 13:23:09
la source

Essayer jGroups si les données à communiquer ne sont pas énormes.

1
répondu zengr 2011-02-19 21:01:42
la source

Que Diriez-vous de http://code.google.com/p/protobuf/ Il est léger.

0
répondu Felix Ng 2011-02-19 22:40:41
la source

comme vous l'avez mentionné, il est évident que vous pouvez envoyer les objets par le réseau, mais c'est une chose coûteuse, sans parler du démarrage d'une JVM séparée.

une autre approche si vous voulez simplement séparer vos différents mondes à l'intérieur d'une JVM est de charger les classes avec des classloaders différents. [email protected]!= [email protected] s'ils sont chargés par CL1 et CL2 comme chargeurs de classe frères.

pour permettre les communications entre [email protected] et [email protected] vous pouvez avoir trois les chargeurs de classe.

  • CL1 qui se charge de fabrication1
  • CL2 qui charge process2 (mêmes classes que dans CL1)
  • CL3 qui charge les classes de communication (POJOs et Service).

Maintenant vous laissez CL3 être le classloader parent de CL1 et CL2.

dans les classes chargées par CL3 vous pouvez avoir une fonctionnalité de communication légère envoyer/recevoir (envoyer (Pojo) / recevoir(Pojo)) les POJOs entre les classes de CL1 et les classes de CL2.

dans CL3 vous exposez un service statique qui permet aux implémentations de CL1 et CL2 register d'envoyer et de recevoir les POJOs.

0
répondu Niclas 2015-04-26 00:55:37
la source

Autres questions sur