Qual è il modo migliore per condividere istanze di oggetti business tra app Web Java usando JBoss e Spring?

StackOverflow https://stackoverflow.com/questions/268129

Domanda

Al momento abbiamo un'applicazione web che carica un contesto di applicazione Spring che crea un'istanza di una pila di oggetti business, oggetti DAO e Hibernate. Vorremmo condividere questo stack con un'altra applicazione Web, per evitare di avere più istanze degli stessi oggetti.

Abbiamo esaminato diversi approcci; esponendo gli oggetti usando JMX o JNDI o usando EJB3.

I diversi approcci hanno tutti i loro problemi e stiamo cercando un metodo leggero.

Qualche suggerimento su come risolverlo?

Modifica: ho ricevuto commenti che mi chiedono di elaborare un po ', quindi ecco qui:

Il problema principale che vogliamo risolvere è che vogliamo avere solo un'istanza di Hibernate. Ciò è dovuto a problemi con l'annullamento della cache di 2 ° livello di Hibernate durante l'esecuzione di diverse applicazioni client che funzionano con la stessa origine dati. Inoltre, lo stack business / DAO / Hibernate sta diventando piuttosto grande, quindi non duplicarlo ha più senso.

Innanzitutto, abbiamo cercato di esaminare come il solo livello aziendale potesse essere esposto ad altre app Web e Spring offre il wrapping JMX al prezzo di una piccola quantità di XML. Tuttavia, non siamo stati in grado di associare le entità JMX all'albero JNDI, quindi non siamo riusciti a cercare gli oggetti dalle app Web.

Quindi abbiamo provato a collegare il livello aziendale direttamente a JNDI. Anche se Spring non ha offerto alcun metodo per questo, usare JNDITemplate per legarli era anche banale. Ciò ha comportato diversi nuovi problemi: 1) Il responsabile della sicurezza nega l'accesso al classloader RMI, quindi il client non è riuscito una volta che abbiamo tentato di invocare metodi sulla risorsa JNDI. 2) Una volta risolti i problemi di sicurezza, JBoss ha lanciato IllegalArgumentException: object non è un'istanza di classe dichiarante. Un po 'di lettura rivela che abbiamo bisogno di implementazioni stub per le risorse JNDI, ma questo sembra un sacco di seccatura (forse la primavera può aiutarci?)

Non abbiamo ancora esaminato troppo EJB, ma dopo i primi due tentativi mi chiedo se ciò che stiamo cercando di ottenere sia possibile.

Per riassumere ciò che stiamo cercando di ottenere: un'istanza di JBoss, diverse app Web che utilizzano una pila di oggetti business sopra il livello DAO e Hibernate.

Cordiali saluti,

Nils

È stato utile?

Soluzione

Le applicazioni Web sono distribuite sullo stesso server?

Non posso parlare per Spring, ma è semplice spostare la tua logica aziendale nel livello EJB usando Session Beans.

L'organizzazione dell'applicazione è semplice. La logica passa ai bean di sessione e questi bean di sessione sono raggruppati in un singolo jar come un artefatto Java EE con un file ejb-jar.xml (in EJB3, questo sarà probabilmente praticamente vuoto).

Quindi raggruppa le tue classi Entity in un file jar separato.

Successivamente, costruirai ciascuna app Web nel suo file WAR.

Infine, tutti i vasetti e le guerre sono raggruppati in un EE Java EE, con il file application.xml associato (di nuovo, questo sarà probabilmente abbastanza minimale, semplicemente enumerando i vasetti nell'EAR).

Questo EAR è distribuito all'ingrosso sul server delle app.

Ogni WAR è effettivamente indipendente: le proprie sessioni, i propri percorsi di contesto, ecc. Ma condividono il back-end EJB comune, quindi hai solo una cache di secondo livello.

Utilizzate anche riferimenti locali e chiamate semantiche per parlare con i bean poiché sono sullo stesso server. Non sono necessarie chiamate remote qui.

Penso che questo risolva abbastanza bene il problema che stai riscontrando, ed è abbastanza semplice in Java EE 5 con EJB 3.

Inoltre, puoi sempre usare Spring per gran parte del tuo lavoro, a quanto ho capito, ma non sono una persona Spring, quindi non posso parlare con i dettagli.

Altri suggerimenti

Che dire di spring parentContext? Dai un'occhiata a questo articolo:

http://springtips.blogspot.com /2007/06/using-shared-parent-application-context.html

Terracotta potrebbe essere adatto qui (divulgazione: sono uno sviluppatore di Terracotta). La terracotta raggruppa in modo trasparente oggetti Java a livello JVM e si integra con Spring e Hibernate. È gratuito e open source.

Come hai detto, il problema di più di un'app Web client che utilizza una cache L2 sta mantenendo sincronizzate quelle cache. Con Terracotta è possibile raggruppare una singola cache Hibernate L2. Ogni nodo client funziona con la sua copia di quella cache cluster e Terracotta lo mantiene sincronizzato. Questo link spiega di più.

Per quanto riguarda i tuoi oggetti business, puoi utilizzare Integrazione della primavera per raggruppare i bean: ogni app Web può condividere istanze di bean cluster e Terracotta mantiene sincronizzato lo stato del cluster in modo trasparente.

In realtà, se vuoi una soluzione leggera e non hai bisogno di transazioni o cluster, usa il supporto Spring per RMI. Permette di esporre i bean Spring in remoto usando semplici annotazioni nelle ultime versioni. Vedi http://static.springframework.org/spring/docs /2.0.x/reference/remoting.html .

Dovresti dare un'occhiata all'applicazione web di riferimento di Terracotta - Examinator. Ha la maggior parte dei componenti che stai cercando: ha Hibernate, JPA e Spring con un backend MySQL.

È stato pre-ottimizzato per scalare fino a 16 nodi, 20k utenti simultanei.

Dai un'occhiata qui: http://reference.terracotta.org/examinator

Grazie per le risposte finora. Non siamo ancora del tutto lì, ma abbiamo provato alcune cose ora e vediamo le cose più chiaramente. Ecco un breve aggiornamento:

La soluzione che sembra essere la più praticabile è EJB. Tuttavia, ciò richiederà alcune modifiche nel nostro codice, quindi non implementeremo completamente quella soluzione in questo momento. Sono quasi sorpreso che non siamo riusciti a trovare alcune funzionalità di Spring per aiutarci qui.

Abbiamo anche provato la route JNDI, che termina con la necessità di stub per tutte le interfacce condivise. Sembra una seccatura, considerando che comunque tutto è sullo stesso server.

Ieri abbiamo avuto una piccola svolta con JMX. Sebbene JMX non sia sicuramente pensato per questo tipo di utilizzo, abbiamo dimostrato che può essere fatto - senza modifiche al codice e una quantità minima di XML (un grande grazie a Spring per MBeanExporter e MBeanProxyFactoryBean). Gli svantaggi principali di questo metodo sono le prestazioni e il fatto che le nostre classi di dominio devono essere condivise tramite la cartella server / lib di JBoss. Ad esempio, dobbiamo rimuovere alcune dipendenze dai nostri WAR e spostarli su server / lib, altrimenti otteniamo ClassCastException quando il livello aziendale restituisce oggetti dal nostro modello di dominio. Capisco perfettamente perché ciò accada, ma non è l'ideale per ciò che stiamo cercando di ottenere.

Ho pensato che fosse giunto il momento di un piccolo aggiornamento, perché la soluzione che sembra essere la migliore impiegherà del tempo per essere implementata. Pubblicherò le nostre scoperte qui una volta fatto quel lavoro.

Spring ha un punto di integrazione che potrebbe interessarti: nterceptor per iniezione EJB 3 . Ciò consente di accedere ai bean di primavera dagli EJB.

Non sono davvero sicuro di ciò che stai cercando di risolvere; alla fine della giornata ogni jvm avrà replicato istanze degli oggetti o stub che rappresentano oggetti esistenti su un altro server (logico).

Potresti, impostare un terzo server 'business logic' che ha un'API remota che le tue due app web potrebbero chiamare. La soluzione tipica è usare EJB, ma penso che la primavera abbia opzioni di remoting integrate nel suo stack.

L'altra opzione è quella di utilizzare una qualche forma di architettura cache condivisa ... che sincronizzerà le modifiche agli oggetti tra i server, ma hai ancora due serie di istanze.

Dai un'occhiata a JBossCache . Ti consente di condividere / replicare facilmente mappe di dati tra istanze JVM multiple (stessa casella o diverse). È facile da usare e ha molte opzioni di protocollo a livello di filo (TCP, UDP Multicast, ecc.).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top