2008-11-06 14 views
14

Actualmente tenemos una aplicación web que carga un contexto de aplicación Spring que crea una instancia de una pila de objetos comerciales, objetos DAO e Hibernate. Nos gustaría compartir esta pila con otra aplicación web, para evitar tener múltiples instancias de los mismos objetos.¿Cuál es la mejor forma de compartir instancias de objetos comerciales entre aplicaciones web Java usando JBoss y Spring?

Hemos examinado varios enfoques; exponer los objetos usando JMX o JNDI, o usando EJB3.

Los diferentes enfoques tienen todos sus problemas, y estamos buscando un método liviano.

¿Alguna sugerencia para resolver este problema?

Edición: He recibido, solicitar observaciones que yo elaborar un poco, así que aquí va:

El principal problema que queremos resolver es que queremos tener sólo una instancia de hibernación. Esto se debe a problemas con la invalidación de la memoria caché de segundo nivel de Hibernate cuando se ejecutan varias aplicaciones cliente que trabajan con la misma fuente de datos. Además, la pila de negocios/DAO/Hibernate está creciendo bastante grande, por lo que no duplicarlo tiene más sentido.

En primer lugar, tratamos de ver cómo la capa de negocios por sí sola podría estar expuesta a otras aplicaciones web, y Spring ofrece JMX envolviendo al precio de una pequeña cantidad de XML. Sin embargo, no pudimos vincular las entidades JMX al árbol JNDI, por lo que no pudimos buscar los objetos desde las aplicaciones web.

Luego intentamos unir la capa de negocios directamente a JNDI. Aunque Spring no ofreció ningún método para esto, usar JNDITemplate para vincularlos también era trivial. Pero esto dio lugar a varios problemas nuevos: 1) El administrador de seguridad niega el acceso al cargador de clases RMI, por lo que el cliente falló una vez que intentamos invocar métodos en el recurso JNDI. 2) Una vez que se resolvieron los problemas de seguridad, JBoss lanzó IllegalArgumentException: object no es una instancia de declaración de clase. Un poco de lectura revela que necesitamos implementaciones de stub para los recursos JNDI, pero esto parece una gran molestia (¿quizás Spring nos puede ayudar?)

Aún no hemos analizado demasiado a EJB, pero después del primero Dos intentos Me pregunto si lo que estamos tratando de lograr es posible.

Para resumir lo que estamos tratando de lograr: una instancia de JBoss, varias aplicaciones web que utilizan una pila de objetos comerciales sobre la capa DAO e Hibernate.

Saludos,

Nils

+0

Podría comentar 1. ¿Qué problema está tratando de resolver? 2. Los problemas que encontraste con los enfoques respectivos que mencionas. Esto permitiría una respuesta más centrada ... – johnstok

+0

Era difícil decirlo todo en 300 caracteres, así que edité la pregunta para agregar más detalles :-) –

Respuesta

5

¿Las aplicaciones web se implementan en el mismo servidor?

No puedo hablar de Spring, pero es sencillo mover su lógica empresarial al nivel EJB utilizando Session Beans.

La organización de la aplicación es sencilla. La lógica entra en beans de sesión, y estos beans de sesión se agrupan en un solo jar como un artefacto de Java EE con un archivo ejb-jar.xml (en EJB3, esto probablemente estará prácticamente vacío).

Luego agrupe las clases de entidad en un archivo jar separado.

A continuación, compilará cada aplicación web en su propio archivo WAR.

Finalmente, todas las jarras y las guerras están agrupadas en un EEE de Java EE, con el archivo application.xml asociado (de nuevo, esto probablemente será bastante mínimo, simplemente enumerando los frascos en el EAR).

Este EAR se implementa al por mayor en el servidor de la aplicación.

Cada WAR es efectivamente independiente: sus propias sesiones, sus propias rutas de contexto, etc. Pero comparten el back end EJB común, por lo que solo tiene una única memoria caché de segundo nivel.

También utiliza referencias locales y semántica de llamadas para hablar con los EJB ya que están en el mismo servidor. No hay necesidad de llamadas remotas aquí.

Creo que esto resuelve bastante bien el problema que está teniendo, y su es bastante sencillo en Java EE 5 con EJB 3.

Además, todavía se puede usar un muelle de gran parte de su trabajo, como lo entiendo , pero no soy una persona de Spring así que no puedo hablar con los detalles.

+0

Sí, todo está implementado en el mismo servidor. Esto se ve bastante interesante, daré una oportunidad a EJB hoy. Mi punto sobre Spring es que ofrece envolver los frijoles, por ej. JMX sin ningún código, pero aparentemente no para EJB. De todos modos, veo el enfoque de EJB hoy. –

-1

Echa un vistazo a JBossCache. Le permite compartir/replicar mapas de datos fácilmente entre varias instancias de JVM (el mismo cuadro o diferente). Es fácil de usar y tiene muchas opciones de protocolo de nivel de cable (TCP, UDP Multicast, etc.).

3

Terracotta podría ser una buena opción aquí (revelación: soy un desarrollador de Terracota). Terracota agrupa de forma transparente objetos Java en el nivel JVM y se integra con Spring e Hibernate. Es gratis y de código abierto.

Como dijiste, el problema de más de una aplicación web cliente que utiliza una caché L2 es mantener esas cachés sincronizadas. Con Terracotta puedes agrupar un solo caché Hibernate L2. Cada nodo de cliente trabaja con su copia de ese caché agrupado, y Terracotta lo mantiene sincronizado. This link explica más.

En cuanto a sus objetos comerciales, puede utilizar Spring integration de Terracotta para agrupar sus beans: cada aplicación web puede compartir instancias de beans clúster, y Terracotta mantiene el estado de clúster sincronizado de forma transparente.

0

No estoy seguro de lo que intentas resolver; al final del día, cada jvm tendrá instancias replicadas de los objetos, o talones que representen objetos existentes en otro servidor (lógico).

Puede configurar un tercer servidor de "lógica de negocios" que tenga una aplicación remota a la que puedan llamar sus dos aplicaciones web. La solución típica es usar EJB, pero creo que la primavera tiene opciones remotas integradas en su pila.

La otra opción es usar alguna forma de arquitectura de caché compartida ... que sincronizará los cambios de objeto entre los servidores, pero aún tiene dos conjuntos de instancias.

+0

No es así si utiliza Terracotta –

2

En realidad, si quiere una solución liviana y no necesita transacciones o clústeres simplemente use el soporte de Spring para RMI. Permite exponer Spring beans de forma remota utilizando anotaciones simples en las últimas versiones. Ver http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.

+0

He utilizado este enfoque para acceder a los beans Spring compartidos desde una aplicación web. Aunque funciona, creo que todavía hay una solución mejor/más limpia. – Mark

+0

Si no le gusta RMI, Spring ofrece algunas otras opciones de comunicación remota: Hessian, Burlap y HttpInvoker (solución de conexión remota de Spring - serialización de Java a través de HTTP). Por supuesto, siempre hay servicios web también. –

1

Gracias por sus respuestas hasta el momento. Todavía no estamos del todo allí, pero hemos intentado algunas cosas ahora y vemos las cosas más claramente. Aquí hay una breve actualización:

La solución que parece ser la más viable es EJB. Sin embargo, esto requerirá una cierta cantidad de cambios en nuestro código, por lo que no vamos a implementar completamente esa solución en este momento. Estoy casi sorprendido de que no hayamos podido encontrar alguna función de Spring para ayudarnos aquí.

También hemos probado la ruta JNDI, que termina con la necesidad de stubs para todas las interfaces compartidas. Esto se siente como una molestia, teniendo en cuenta que todo está en el mismo servidor de todos modos.

Ayer, tuvimos un pequeño avance con JMX. Aunque definitivamente JMX no está diseñado para este tipo de uso, hemos demostrado que se puede hacer, sin cambios de código y con una cantidad mínima de XML (un gran agradecimiento a Spring para MBeanExporter y MBeanProxyFactoryBean). Los principales inconvenientes de este método son el rendimiento y el hecho de que nuestras clases de dominio se deben compartir a través de la carpeta server/lib de JBoss. Es decir, tenemos que eliminar algunas dependencias de nuestros WAR y moverlas a server/lib, de lo contrario obtenemos ClassCastException cuando la capa de negocios devuelve objetos de nuestro propio modelo de dominio. Entiendo completamente por qué sucede esto, pero no es ideal para lo que estamos tratando de lograr.

Pensé que era hora de una pequeña actualización, porque lo que parece ser la mejor solución llevará algún tiempo implementarlo. Publicaré nuestros hallazgos aquí una vez que hayamos hecho ese trabajo.

+0

Ha sido sugerido varias veces en este hilo por mí y por otros, pero ¿has mirado Terracotta? A diferencia de todas las otras soluciones presentadas hasta el momento, está diseñado explícitamente para compartir estados, que es lo que usted solicitó. –

2

Debería echar un vistazo a la Aplicación web de referencia de terracota - Examinador. Tiene la mayoría de los componentes que está buscando, tiene Hibernate, JPA y Spring con un back-end MySQL.

Ha sido preajustado para escalar hasta 16 nodos, 20k usuarios concurrentes.

Échale un vistazo aquí: http://reference.terracotta.org/examinator

1

primavera tiene un punto de integración que pueda ser de su interés: EJB 3 injection nterceptor. Esto le permite acceder a los granos de primavera desde los EJB.

Cuestiones relacionadas