2008-11-06 2 views
14

Nous avons actuellement une application Web qui charge un contexte d'application Spring qui instancie une pile d'objets métier, d'objets DAO et d'Hibernate. Nous aimerions partager cette pile avec une autre application web, pour éviter d'avoir plusieurs instances des mêmes objets.Quelle est la meilleure façon de partager des instances d'objet métier entre des applications Web Java à l'aide de JBoss et Spring?

Nous avons examiné plusieurs approches; exposer les objets en utilisant JMX ou JNDI, ou en utilisant EJB3.

Les différentes approches ont toutes leurs problèmes, et nous recherchons une méthode légère.

Des suggestions sur comment résoudre ce problème?

Edit: J'ai reçu des commentaires me demandant d'élaborer un peu, donc voilà:

Le principal problème que nous voulons résoudre est que nous voulons avoir une seule instance de veille prolongée. Cela est dû à des problèmes d'invalidation du cache de second niveau d'Hibernate lors de l'exécution de plusieurs applications client travaillant avec la même source de données. De plus, la pile business/DAO/Hibernate est de plus en plus grande, donc ne pas la dupliquer n'a pas plus de sens. En premier lieu, nous avons essayé de voir comment la couche de gestion seule pouvait être exposée à d'autres applications Web, et Spring offre l'encapsulation JMX au prix d'une petite quantité de XML. Cependant, nous n'avons pas pu lier les entités JMX à l'arborescence JNDI, donc nous n'avons pas pu rechercher les objets des applications Web.

Ensuite, nous avons essayé de lier la couche de gestion directement à JNDI. Bien que Spring n'offrait aucune méthode pour cela, l'utilisation de JNDITemplate pour les lier était également triviale. Mais cela a conduit à plusieurs nouveaux problèmes: 1) Le gestionnaire de sécurité refuse l'accès au classloader RMI, de sorte que le client a échoué une fois que nous avons essayé d'invoquer des méthodes sur la ressource JNDI. 2) Une fois les problèmes de sécurité résolus, JBoss a lancé IllegalArgumentException: l'objet n'est pas une instance de classe déclarante. Un peu de lecture révèle que nous avons besoin d'implémentations stub pour les ressources JNDI, mais cela semble beaucoup de tracas (peut-être que Spring peut nous aider?)

Nous n'avons pas encore trop regardé l'EJB, mais après le premier deux essais je me demande si ce que nous essayons d'accomplir est tout possible. Pour résumer ce que nous essayons de réaliser: Une instance JBoss, plusieurs applications Web utilisant une pile d'objets métier au-dessus de la couche DAO et Hibernate.

Meilleures salutations,

Nils

+0

Pourriez-vous commenter sur 1. Quel problème vous essayez de résoudre; 2. Les problèmes que vous avez trouvés avec les approches respectives que vous mentionnez. Cela permettrait une réponse plus ciblée ... – johnstok

+0

Il était difficile de tout dire en 300 caractères, donc j'ai édité la question pour ajouter plus de détails :-) –

Répondre

5

Les applications Web sont-elles déployées sur le même serveur?

Je ne peux pas parler pour Spring, mais il est facile de déplacer votre logique métier vers le niveau EJB en utilisant des beans Session.

L'organisation de l'application est simple. La logique va dans les beans session, et ces beans session sont regroupés dans un seul jar comme un artefact Java EE avec un fichier ejb-jar.xml (dans EJB3, ce sera probablement pratiquement vide).

Ensuite, regroupez les classes Entity dans un fichier JAR distinct.

Ensuite, vous allez construire chaque application web dans leur propre fichier WAR. Enfin, tous les jars et les guerres sont regroupés dans un fichier EAR Java EE, avec le fichier application.xml associé (ce qui sera probablement tout à fait minime, en énumérant simplement les jarres dans le fichier EAR). Cet EAR est déployé en gros sur le serveur de l'application. Chaque WAR est effectivement indépendant - ses propres sessions, ses propres chemins de contexte, etc. Mais ils partagent le backend EJB commun, donc vous n'avez qu'un seul cache de second niveau.

Vous utilisez également des références locales et appelez la sémantique pour communiquer avec les EJB car ils se trouvent sur le même serveur. Pas besoin d'appels à distance ici.

Je pense que cela résout bien le problème que vous rencontrez, et son est assez simple en Java EE 5 avec EJB 3.

En outre, vous pouvez toujours utiliser Spring pour une grande partie de votre travail, que je comprends , mais je ne suis pas une personne du printemps, donc je ne peux pas parler aux détails.

+0

Oui, tout est déployé sur le même serveur. Cela semble assez intéressant, je vais donner une chance à EJB aujourd'hui. Mon point au sujet du printemps est qu'il offre d'emballer les haricots pour, par exemple, JMX sans aucun code, mais apparemment pas pour EJB. Quoi qu'il en soit, je regarde l'approche EJB aujourd'hui. –

-1

Jetez un oeil à JBossCache. Il vous permet de partager/répliquer facilement des cartes de données entre plusieurs instances JVM (même boîte ou différente). Il est facile à utiliser et dispose de nombreuses options de protocole de niveau fil (TCP, UDP Multicast, etc.).

3

Terracotta peut être un bon ajustement ici (divulgation: je suis un développeur pour Terracotta). Terracotta regroupe de manière transparente les objets Java au niveau de la JVM et s'intègre à Spring et à Hibernate. C'est gratuit et open source. Comme vous l'avez dit, le problème de plus d'une application Web client utilisant un cache L2 maintient ces caches synchronisés. Avec Terracotta, vous pouvez mettre en cluster un seul cache Hibernate L2. Chaque nœud client travaille avec sa copie de ce cache en cluster, et Terracotta le garde synchronisé. This link explique plus. En ce qui concerne vos objets de gestion, vous pouvez utiliser le Spring integration de Terracotta pour regrouper vos beans - chaque application Web peut partager des instances de beans en cluster, et Terracotta maintient l'état clusterisé en synchronisation de façon transparente.

0

Je ne suis pas vraiment sûr de ce que vous essayez de résoudre; à la fin de la journée, chaque jvm aura des instances répliquées des objets, ou des stubs représentant des objets existant sur un autre serveur (logique).

Vous pouvez configurer un troisième serveur de «logique applicative» disposant d'une API distante que vos deux applications Web peuvent appeler. La solution typique est d'utiliser EJB, mais je pense que le printemps a des options de remoting intégrées dans sa pile.

L'autre option consiste à utiliser une forme d'architecture de cache partagé ... qui synchronisera les modifications d'objet entre les serveurs, mais vous disposez toujours de deux ensembles d'instances.

+0

Pas si vous utilisez Terracotta –

2

En fait, si vous voulez une solution légère et n'avez pas besoin de transactions ou de clusters, utilisez simplement le support Spring pour RMI. Il permet d'exposer les beans Spring à distance en utilisant des annotations simples dans les dernières versions. Voir http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.

+0

J'ai utilisé cette approche pour accéder aux beans Spring partagés à partir d'une application web. Cela fonctionne bien que je pense toujours qu'il y a probablement une solution meilleure/plus propre. – Mark

+0

Si vous n'aimez pas RMI, Spring propose quelques autres options d'accès à distance - Hessian, Burlap et HttpInvoker (solution d'accès distant personnalisée de Spring - sérialisation Java sur HTTP). Bien sûr, il y a toujours des services Web. –

1

Nous vous remercions de vos réponses à ce jour. Nous ne sommes pas encore tout à fait là, mais nous avons essayé quelques choses maintenant et voir les choses plus clairement. Voici une petite mise à jour:

La solution qui semble la plus viable est l'EJB. Cependant, cela nécessitera un certain nombre de changements dans notre code, donc nous n'allons pas implémenter complètement cette solution maintenant. Je suis presque surpris que nous n'ayons pas été en mesure de trouver une fonctionnalité de Spring pour nous aider ici.

Nous avons également essayé la route JNDI, qui se termine par le besoin de stubs pour toutes les interfaces partagées. Cela ressemble à beaucoup de tracas, compte tenu du fait que tout est sur le même serveur de toute façon.

Hier, nous avons eu une petite pause avec JMX. Bien que JMX ne soit certainement pas destiné à ce genre d'utilisation, nous avons prouvé que cela peut être fait - sans aucun changement de code et une quantité minimale de XML (un grand merci à Spring pour MBeanExporter et MBeanProxyFactoryBean). Les principaux inconvénients de cette méthode sont les performances et le fait que nos classes de domaine doivent être partagées via le dossier serveur/lib de JBoss. Par exemple, nous devons supprimer certaines dépendances de nos WAR et les déplacer vers server/lib, sinon nous obtenons ClassCastException lorsque la couche de gestion renvoie des objets de notre propre modèle de domaine. Je comprends parfaitement pourquoi cela arrive, mais ce n'est pas idéal pour ce que nous essayons d'accomplir.

Je pensais qu'il était temps pour une petite mise à jour, parce que ce qui semble être la meilleure solution prendra du temps à mettre en œuvre. Je posterai nos résultats ici une fois que nous aurons fait ce travail.

+0

Il a été suggéré plusieurs fois sur ce sujet par moi-même et d'autres, mais avez-vous regardé Terracotta? Contrairement à toutes les autres solutions présentées jusqu'ici, elle est conçue explicitement pour le partage d'état, ce que vous avez demandé. –

2

Vous devriez jeter un coup d'œil à l'application web de référence Terracotta - Examinator. Il a la plupart des composants que vous recherchez - il a Hibernate, JPA et Spring avec un backend MySQL.

Il a été pré-réglé pour mettre à l'échelle jusqu'à 16 nœuds, 20 000 utilisateurs simultanés.

Check it out ici: http://reference.terracotta.org/examinator

1

Spring ne un point d'intégration qui pourrait être vous intéresser: EJB 3 injection nterceptor. Cela vous permet d'accéder aux haricots de printemps à partir des EJB.

Questions connexes