Un MDB singleton in un cluster di JBoss AS 4.x

ottobre 20, 2006 at 7:45 PM 16 commenti

Finisce anche questa settimana… contraddistinta dal’imperversare dell’influenza in ufficio (…proprio ora sono di ritorno dalla visita medica). Entro questa settimana mi ero prefissato di tirar su un singleton MDB in un ambiente JBoss clusterizzato e, nonostante le notti insonni per il naso completamente chiuso, alla fine ci sono riuscito.

JBoss Messaging è un JMS Provider ad altissime prestazioni, è una completa riscrittura di JBossMQ (il JMS Provider di default in JBoss AS 4.x) e sarà il JMS Provider di default in JBoss AS 5.x. Purtroppo, alla sua attuale versione, 1.0.1.GA, JBoss Messaging non offre supporto al clustering e dovrò pertanto utilizzare JBossMQ, riservandomi la possibilità di switchare a JBoss Messaging quando verrà rilasciata la versione 1.0.2. Il passaggio non dovrebbe riservare grosse criticità in quanto JBoss Messaging implementa JMS 1.1 ed è compatibile con JMS 1.0.2b, pertanto il codice JMS scritto per JBossMQ può girare senza alcuna modifica in JBoss Messaging… ma questa è qualcosa che potrò confermare solo al momento opportuno.

Prima di addentrarmi nella configurazione JMS, ho preferito focalizzare bene le mie conoscenze sulla gestione del cluster da parte di JBoss.

JBoss offre pieno supporto al clustering, permettendo così la distribuzione del carico su diversi servers. Il componente singolo del cluster è detto nodo (un’istanza di JBoss) e più nodi possono essere raggruppati insieme definendo la stessa “partition” name nel run.

Per es.

run.sh -c MyApp -b 192.168.0.10 -Djboss.partition.name=myPartition
run.sh -c MyApp -b 192.168.0.11 -Djboss.partition.name=myPartition

La maggior parte dei servizi esposti da JBoss AS (JNDI, EJB, RMI, JBoss Remoting, ecc.) richiede che il client ottenga (tramite lookup e download) un oggetto stub (o proxy). Lo stub è generato dal server ed implementa le interfacce di business del servizio. A questo punto il client effettua chiamate “locali” sull’oggetto stub. In un ambiente clusterizzato, lo stub generato dal server è anche un interceptor (proxy) che sa come indirizzare le chiamate ai nodi del cluster (conosce gli indirizzi ip dei nodi disponibili, l’algoritmo per la distribuzione del carico e sa come rimediare ad una chimata fallita). Ogni volta che viene richiesto un servizio viene aggiornato lo stub interceptor alle ultime modifiche nella composizione del cluster.

Lookup Servizio con una richiesta non-HTTP

Quando i servizi richiesti viaggiano su HTTP (per es. WebService) al client non è richiesto alcun oggetto stub, il ruolo dell’interceptor viene effettuato da un Load-balancer.

Lookup Servizio con una richiesta HTTP

Il servizio di JNDI è vitale per un application server e, in un ambiente clusterizzato di JBoss, è l’HA-JNDI (High Availability JNDI) il servizio che gestisce questo contesto nel cluster. L’albero di contesto JNDI di un cluster è sempre disponibile finchè c’è almeno un nodo nel cluster. A sua volta, ogni nodo del cluster, mantiene un proprio contesto JNDI (locale). Dal lato server, ogni new InitialContext() crea un contesto JNDI locale (per es. le EJB homes). Nel caso di una lookup remota, invece, se l’oggetto richiesto è disponibile nel contesto JNDI clusterizzato allora viene ritornato, altrimenti viene effettuata una lookup nel contesto JNDI locale. Se anche quest’ultima non ritorna l’oggetto richiesto, allora l’HA-JNDI chiede a tutti i nodi del cluster se nella loro JNDI locale è presente l’oggetto richiesto. Se anche questa lookup fallisce viene restituita una NameNotFoundException. Pertanto, un client JNDI deve essere a conoscenza dell’HA-JNDI cluster e come parametro PROVIDER_URL per la lookup dovrà passare la lista degli ip dei nodi del cluster con la porta HA-JNDI (1100).

Per esempio:

Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "192.168.0.10:1100,192.168.0.11:1100");
return new InitialContext(p);

Tutta questa pappardella mi è servita per arrivare al punto cruciale: a partire dalla versione 3.2.4, JBoss AS supporta l’high availability JMS (HA-JMS) nella configurazione “all”, implementato come servizio singleton clusterizzato in modalità fail-over (se il nodo master diventa irraggiungibile, allora verrà nominato un nuovo master su cui verrà deploiato l’HA-JMS).
Per poter utilizzare l’HA-JMS occorre configurare i servizi JMS in modo identico su ogni nodo del cluster (nella directory $JBOSS_SERVER/deploy-hasingleton/jms). Di default, tutti i servizi JMS vengono persistiti su Hypersonic (hsqldb), un database java che risiede in memoria, il quale è appropriato in fase di sviluppo e di test, ma non è assolutamente adatto in un ambiente di produzione. Infatti in caso di avvio con servizi JMS di default, si riceverebbe un warning sul log di console:

JBoss Messaging Warning: DataSource connection transaction isolation should be READ_COMMITTED, but it is currently NONE.
Using an isolation level less strict than READ_COMMITTED may lead to data consistency problems.
Using an isolation level more strict than READ_COMMITTED may lead to deadlock.

La prima cosa da fare è quindi settare un db esterno per la persistenza. Dal momento che i servizi JMS utilizzano il datasource di Default (DefaultDS) le strade che si possono percorrere sono 2:

  • creo un datasource di default che punta la mio db esterno
  • creo un datasource con un mio JNDI name e mi ricordo di modificare anche i files xml dei servizi JMS in modo che utilizzino il mio datasource.

Anche se l’approccio KISS rimane sempre il mio preferito, ho optato per la seconda soluzione, se non altro per avere una visuale più pulita (ammesso che questa possa essere una motivazione valida).

Creo quindi il file del datasource con un mio JNDI Name, che punta ad un database di Oracle10g.

myapp-jms-oracle-ds.xml

<datasources>
    <local-tx-datasource>
        <jndi-name>MyOracleDS</jndi-name>
        <connection-url>jdbc:oracle:thin:@192.168.0.15:1521:XE</connection-url>
        <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
        <user-name>myuser</user-name>
        <password>myuser</password>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
        <metadata>
            <type-mapping>Oracle9i</type-mapping>
        </metadata>
    </local-tx-datasource>
</datasources>

Elimino il file hsqldb-jdbc2-service.xml e creo il file per la configurazione dei servizi di persistenza e cache configurato ad hoc per un db oracle (per altri db, i files di configurazione sono disponibili in $JBOSS_HOME/doc/examples/jms).

myapp-jms-oracle-jdbc2-service.xml (il file può avere qualsiasi nome che rispetti il pattern ..*-service.xml)

<server>
    <mbean code="org.jboss.mq.server.jmx.DestinationManager" name="jboss.mq:service=DestinationManager">
        <depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache</depends>
        <depends optional-attribute-name="PersistenceManager">jboss.mq:service=PersistenceManager</depends>
        <depends optional-attribute-name="StateManager">jboss.mq:service=StateManager</depends>
    </mbean>    

    <mbean code="org.jboss.mq.server.MessageCache" name="jboss.mq:service=MessageCache">
        <attribute name="HighMemoryMark">50</attribute>
        <attribute name="MaxMemoryMark">60</attribute>
        <attribute name="CacheStore">jboss.mq:service=PersistenceManager</attribute>
    </mbean>    

    <mbean code="org.jboss.mq.pm.jdbc2.PersistenceManager" name="jboss.mq:service=PersistenceManager">
        <depends optional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=MyOracleDS</depends>
        <attribute name="SqlProperties">
            INSERT_EMPTY_BLOB = INSERT INTO JMS_MESSAGES (MESSAGEID, DESTINATION, MESSAGEBLOB, TXID, TXOP) VALUES(?,?,EMPTY_BLOB(),?,?)
            LOCK_EMPTY_BLOB = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE MESSAGEID = ? AND DESTINATION = ? FOR UPDATE
            BLOB_TYPE=BINARYSTREAM_BLOB
            INSERT_TX = INSERT INTO JMS_TRANSACTIONS (TXID) values(?)
            INSERT_MESSAGE = INSERT INTO JMS_MESSAGES (MESSAGEID, DESTINATION, MESSAGEBLOB, TXID, TXOP) VALUES(?,?,?,?,?)
            SELECT_ALL_UNCOMMITED_TXS = SELECT TXID FROM JMS_TRANSACTIONS
            SELECT_MAX_TX = SELECT MAX(TXID) FROM (SELECT MAX(TXID) AS TXID FROM JMS_TRANSACTIONS UNION SELECT MAX(TXID) AS TXID FROM JMS_MESSAGES)
            DELETE_ALL_TX = DELETE FROM JMS_TRANSACTIONS
            SELECT_MESSAGES_IN_DEST = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE DESTINATION=?
            SELECT_MESSAGE_KEYS_IN_DEST = SELECT MESSAGEID FROM JMS_MESSAGES WHERE DESTINATION=?
            SELECT_MESSAGE = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
            MARK_MESSAGE = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE MESSAGEID=? AND DESTINATION=?
            UPDATE_MESSAGE = UPDATE JMS_MESSAGES SET MESSAGEBLOB=? WHERE MESSAGEID=? AND DESTINATION=?
            UPDATE_MARKED_MESSAGES = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=?
            UPDATE_MARKED_MESSAGES_WITH_TX = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=? AND TXID=?
            DELETE_MARKED_MESSAGES_WITH_TX = DELETE FROM JMS_MESSAGES MESS WHERE TXOP=:1 AND EXISTS (SELECT TXID FROM JMS_TRANSACTIONS TX WHERE TX.TXID = MESS.TXID)
            DELETE_TX = DELETE FROM JMS_TRANSACTIONS WHERE TXID = ?
            DELETE_MARKED_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXID=? AND TXOP=?
            DELETE_TEMPORARY_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXOP='T'
            DELETE_MESSAGE = DELETE FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
            CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES ( MESSAGEID INTEGER NOT NULL, DESTINATION VARCHAR(255) NOT NULL, TXID INTEGER, TXOP CHAR(1),
            MESSAGEBLOB BLOB, PRIMARY KEY (MESSAGEID, DESTINATION) )
            CREATE_IDX_MESSAGE_TXOP_TXID = CREATE INDEX JMS_MESSAGES_TXOP_TXID ON JMS_MESSAGES (TXOP, TXID)
            CREATE_IDX_MESSAGE_DESTINATION = CREATE INDEX JMS_MESSAGES_DESTINATION ON JMS_MESSAGES (DESTINATION)
            CREATE_TX_TABLE = CREATE TABLE JMS_TRANSACTIONS ( TXID INTEGER, PRIMARY KEY (TXID) )
            CREATE_TABLES_ON_STARTUP = TRUE
        </attribute>
        <!-- Uncomment to override the transaction timeout for recovery per queue/subscription, in seconds -->
        <!--attribute name="RecoveryTimeout">0</attribute-->
        <!-- The number of blobs to load at once during message recovery -->
        <attribute name="RecoverMessagesChunk">0</attribute>
    </mbean>    

</server>

…ciò che è importante da modificare è il parametro di binding al datasource scelto (ammesso che si abbia optato per la seconda soluzione). Sempre nella stessa directory è disponibile anche il file hsqldb-jdbc-state-service.xml, che potrebbe indurre a rimuoverlo, in linea con quanto è stato fatto con hsqldb-jdbc2-service.xml. In realtà hsqldb-jdbc-state-service.xml ha un nome abbastanza infelice, infatti la configurazione è adatta a qualsiasi db SQL92 compliant (per pulizia lo rinominerei in myapp-jms-jdbc-state-service.xml). L’unica cosa da modificare è il puntamento al giusto JNDI name, che è settato a DefaultDS. Occorre infine creare il file per la configurazione della coda/e.

myapp-jms-destination-service.xml:

<server>
    <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=MyQueue">
        <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
        <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
        <attribute name="MessageCounterHistoryDayLimit">-1</attribute>
        <attribute name="SecurityConf">
            <security>
                <role name="guest" read="true" write="true"/>
                <role name="publisher" read="true" write="true" create="false"/>
                <role name="noacc" read="false" write="false" create="false"/>
            </security>
        </attribute>
    </mbean>
</server>

Ho preparato un task ant per effettuare il deploy dei servizi JMS personalizzati:

<target name="install-myapp-jms">
    <copy todir="${jboss.server}/deploy-hasingleton/jms" overwrite="yes">
        <fileset file="component/jms/etc/myapp-jms-oracle-ds.xml"/>
        <fileset file="component/jms/etc/myapp-jms-destinations-service.xml"/>
        <fileset file="component/jms/etc/myapp-jms-oracle-jdbc2-service.xml"/>
        <fileset file="component/jms/etc/myapp-jms-jdbc-state-service.xml"/>
    </copy>
    <delete file="${jboss.server}/deploy-hasingleton/jms/hsqldb-jdbc2-service.xml" failonerror="false"/>
</target>

Una volta tirati su i servizi JMS personalizzati, occorre deploiare un solo MDB per tutto il cluster. Creo quindi un MDB semplice che all’arrivo di un messaggio me lo printa sul log.

MyMDB.java:

package test;    

import org.apache.log4j.Logger;
import javax.ejb.MessageDrivenBean;
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenContext;
import javax.jms.MessageListener;
import javax.jms.Message;    

public class MyMDB implements MessageDrivenBean, MessageListener {    

    private static final Logger logWriter = Logger.getLogger(MyMDB.class);    

    /**
     * Message driven context
     */
    private MessageDrivenContext messageDrivenContext;    

    public InboundRisultatiBean() {}    

    public void onMessage(Message message) {
        logWriter.debug("---- Called onMessage() ----");
        logWriter.debug("Messaggio: " + message);
        logWriter.debug("---- Exit onMessage() ----");
    }    

    public void ejbRemove() throws EJBException {}    

    public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) throws EJBException {
        this.messageDrivenContext = messageDrivenContext;
    }    

    public void ejbCreate() {}    

}

Setto la transazione a Required solo per il metodo onMessage().

ejb-jar.xml:

<ejb-jar>
    <enterprise-beans>
        <message-driven>
            <description>Singleton MDB, MyMDB</description>
            <ejb-name>MyMDB</ejb-name>
            <ejb-class>test.MyMDB</ejb-class>
            <transaction-type>Container</transaction-type>
            <acknowledge-mode>Auto-acknowledge</acknowledge-mode>
            <message-driven-destination>
                <destination-type>javax.jms.Queue</destination-type>
            </message-driven-destination>
        </message-driven>
    </enterprise-beans>        

    <assembly-descriptor>
        <container-transaction>
            <method>
                <ejb-name>MyMDB</ejb-name>
                <method-name>onMessage</method-name>
            </method>
            <trans-attribute>Required</trans-attribute>
        </container-transaction>
    </assembly-descriptor>    

</ejb-jar>

Infine setto in jboss.xml il bind dell’MDB alla mia coda e soprattutto scelgo come configuration-name “Singleton Message Driven Bean”, una configurazione già disponibile in JBoss AS senza dover specificare altri parametri nel tag <container-configurations>:

<jboss>
    <enterprise-beans>
        <message-driven>
            <ejb-name>MyMDB</ejb-name>
            <configuration-name>Singleton Message Driven Bean</configuration-name>
            <destination-jndi-name>queue/GTSRisultatiQueue</destination-jndi-name>
        </message-driven>
    </enterprise-beans>
</jboss>

Impacchetto il tutto in un jar e deploio su tutti i nodi nella directory $JBOSS_SERVER/deploy.hasingleton. Se il deploy è effettuato a caldo (hot-deploy), quando tutti i servizi JMS sono stati startati non si dovrebbero ricevere errori, se invece si avvia JBoss con l’mdb già presente in directory si dovrebbe ricevere un errore di JNDI name non trovata (si tratta di una JNDI name dei servizi JMS, per es. CachedConnectionManager, DefaultJMSProvider…).Tutto ciò avviene, in quanto, JBoss tenta di deploiare il jar (e quindi di attaccare l’mdb alla coda) quando ancora i servizi JMS non sono stati avviati.
Una delle soluzioni trovate in rete (che come al solito a me non ha funzionato), è quella di settare a true il parametro RecursiveSearch nel file $JBOSS_SERVER/conf/jboss-service.xml. Con riferimento invece alle dipendenze dei vari servizi di JBoss, ho modificato il file ejb-deployer.xml in $JBOSS_SERVER/deploy aggiungendo la dipendenza a ServerSessionPoolMBean (ultimo servizio JMS ad essere avviato):

<depends>jboss.mq:service=ServerSessionPoolMBean,name=StdJMSPool</depends>

Grazie a quest’ultimo ritocco tutti i tasselli dovrebbero essersi incastrati perfettamente… per verificarlo basta la prova del nove. Ho messo in cluster 3 nodi jboss, deploiando singolarmente il mio mdb. L’mdb è stato creato solo sul nodo su cui ho effettuato per primo il deploy. Ho provato ad inviare con uno stress test una serie di messaggi sulla coda con un client esterno a cui ho fornito la lista di provider url HA-JNDI. Tutti i msg sono stati letti in sequenza (senza concorrenza, essendoci un solo mdb) dall’unico nodo su cui era stato deploiato l’mdb. Infine con mia grande soddisfazione, ho buttato giù il nodo master dell’mdb e automaticamente il cluster ha scelto un nuovo nodo su cui creare l’mdb.

Entry filed under: cluster, jboss, mdb, singleton.

Ripristinare GRUB Servizi JMS transazionali in JBoss AS 4.x

16 commenti Add your own

  • 1. mcaserta  |  ottobre 21, 2006 alle 10:26 PM

    Meriteresti un aumento solo per aver scritto questo post 🙂

    Rispondi
  • 2. ubuntutaker  |  ottobre 22, 2006 alle 9:56 am

    grazie mirko…
    confido nella tua buona parola 😉

    Rispondi
  • 3. bluesman  |  gennaio 29, 2007 alle 4:42 PM

    bell’articolo 🙂
    io con il mio jboss 4.0.3 sto uscendo pazzo…
    il quando tento di connettermi con un client swing ad un server jboss/jms remoto, mi da sempre un errore:
    più o meno
    org.jboss.mq.SpyJMSException cannot authenticate user
    per caso sai cos’è?

    Rispondi
  • 4. ubuntutaker  |  gennaio 31, 2007 alle 11:38 am

    E’ un problema di autenticazione che puoi risolvere nel seguente modo.
    – Nella directory conf/ della partizione jboss c’è il file login-config.xml, aprilo e controlla quale datasource utilizza l’applicaztion “jbossmq” (ed eventualmente fixarlo sul datasource desiderato).
    – Nella directory deploy-hasingleton/jms apri il file di configurazione degli stati (dovrebbe terminare con -state-service.xml). In questo file è necessario che il datasource puntato sia lo stesso di quello inserito precedentemente in login-config.xml. Sempre in questo file si possono definire eventualmente altri account (se non si vogliono utilizzare quelli esistenti). Poniamo per es. di volere inserire il ruolo ‘operatore’ che può scrivere e leggere sulla coda e associamo ad esso un account con username ‘bluesman’ e password ‘bluesman’. Per farlo basta aggiungere tra i tag attribute le due seguenti righe:
    POPULATE.TABLES.{NUMERO_PROGRESSIVO} = INSERT INTO JMS_USERS (USERID, PASSWD) VALUES (‘bluesman’, ‘bluesman’)
    POPULATE.TABLES.{NUMERO_PROGRESSIVO} = INSERT INTO JMS_ROLES (ROLEID, USERID) VALUES (‘operatore’,’bluesman’)
    dove {NUMERO_PROGRESSIVO} è un numero che va incrementato man mano che si aggiungono righe.
    Naturalmente per far funzionare il tutto occorre aggiungere il ruolo con i permessi alla coda, aggiungendo il seguente tag di sicurezza al file destination:

    <attribute name=”SecurityConf”>
    <security>
    <role name=”guest” read=”false” write=”false” create=”false” />
    <role name=”subscriber” read=”true” write=”false” create=”false” />
    <role name=”publisher” read=”true” write=”true” create=”false” />
    </security>
    </attribute>

    Ora per connetterti alla coda userai l’account di bluesman:
    queueConnFactory.createQueueConnection(“bluesman”, “bluesman”);
    Spero ti sia utile 😉

    Rispondi
  • 5. Tommy  |  febbraio 23, 2007 alle 11:39 am

    Ciao, sono capitato su questo post per caso: anche io come te ho fatto un’istallazione di jboss in cluster. La mia ha tre nodi e un ejb stateless deployato in Farm. A monte del cluster ho un apache che smista le chiamate http (con il jk_mod) Mi chiedevo se sapevi come poter effettuare il lookup all’ejb via Http…

    Rispondi
  • 6. Tommy  |  febbraio 23, 2007 alle 1:25 PM

    scusa , mi rispondo da solo: basta cambiare due parametri del lookup:

    Hashtable environment = new Hashtable();
    environment.put(Context.INITIAL_CONTEXT_FACTORY, “org.jboss.naming.HttpNamingContextFactory”);
    environment.put(Context.URL_PKG_PREFIXES, “org.jboss.naming:org.jnp.interfaces”);
    environment.put(Context.PROVIDER_URL, “http://localhost/invoker/JNDIFactory”);
    InitialContext context = new InitialContext(environment);

    Mentre il codice per il lookup non cambia: lato client la cosa sembra essere trasparente, dai pochi test che ho fatto sembra che anche le prestazioni non siano niente male…

    Nel mio caso, visto che davanti al cluster ho un’istanza di Apache ho dovuto anche abilitare il context “invoker” inserendo le opportune righe nel file uriworkermap.properties del modulo jk_mod:

    /invoker/=loadbalancer
    /invoker/*=loadbalancer

    Rispondi
  • 7. ubuntutaker  |  febbraio 28, 2007 alle 11:12 am

    …non mi era mai capitato di dover utilizzare Apache davanti al cluster.
    Me lo segno… 😉

    Rispondi
  • 8. dario  |  marzo 19, 2007 alle 11:18 am

    Ciao,
    devo configurare una coda in modo tale che sia persistente nel senso scope=aplication ed inoltre settare la sua massima dimensione.
    Puoi dirmi come e soprattutto il codice dic onfigurazione?
    Nn riesco a scrivere la sinassi esatta.

    Grazie
    Dario

    Rispondi
  • 9. Fabio  |  marzo 20, 2007 alle 5:57 am

    Bellissimo articolo e mi permetto di farti una domanda sul clustering :). Secondo te il clustering di + istanze di Jboss sullo stesso server funziona? Ho un server con 8G di Ram ma potendo indirizzare solo 2G per processo i restanti sono sprecati e pensavo di creare 3 istanze in cluster come soluzione al problema

    Rispondi
  • 10. ubuntutaker  |  marzo 20, 2007 alle 10:00 am

    per dario:
    Per rendere i messaggi persistenti è necessario legare il servizio di PersistenceManager ad un valido datasource, inserendo come attributo SqlProperties lo schema del db che si intende utilizzare. Il file myapp-jms-oracle-jdbc2-service.xml può essere un valido esempio.
    E’ possibile impostare la massima dimensione a livello di queue inserendo l’attributo MaxDepth nella definizione di una destination service. Se si tenta di inserire un nuovo messaggio in una coda piena si riceve un errore org.jboss.mq.DestinationFullException (per eventuali gestioni).

    Rispondi
  • 11. ubuntutaker  |  marzo 20, 2007 alle 10:19 am

    per Fabio:

    Ci sono due possibili soluzioni:

    1 – Utilizzare due interfacce fisiche facendo il binding di una istanza di JBoss su una interfaccia e della seconda istanza sull’altra interfaccia

    2 – Modificare manualmente le porte dei vari servizi per evitare i conflitti.

    Per la prima soluzione vedo in Hamachi un possibile marchingegno attraverso il quale creare delle interfacce di rete virtuali.

    La seconda soluzione è stata già percorsa dal mio boss, ti riassumo a grandi linee come ha fatto:

    La riga di comando per lanciare il cluster è:
    run.bat -c [server name] -b [ip] -Djboss.partition.name=[partition]
    dove
    [server name] è il nome del server (tra quelli presenti nella directory /server)
    [ip] è l’ip su cui JBoss farà il binding
    [partition] è il nome della partizione che identifica un determinato cluster
    Quindi nel caso di singolo host con due interfacce gli argomenti di -b saranno gli indirizzi delle due interfacce, se l’interfaccia a disposizione è solo uno gli argoomenti di -b saranno uguali, ma sarà necessario modificare le porte su cui ascoltano le due istanze nei seguenti file di configurazione:
    conf/jboss-service.xml
    conf/jboss-minimal.xml
    conf/jacorb.properties (da verificare se necessario)
    deploy/cluster-service.xml
    deploy/jms/hajndi-jms-ds.xml
    deploy/jbossweb-tomcat55.sar/server.xml
    deploy/httpha-invoker.sar/META-INF/jboss-service.xml
    deploy/jboss-ws4ee.sar/META-INF/jboss-service.xml deploy/jbossweb-tomcat55.sar/server.xml deploy/jmx-console.war/cluster/clusterView.jsp deploy/juddi-service.sar/juddi.war/WEB-INF/juddi.properties deploy/management/console-mgr.sar/web-console.war/WEB-INF/classes/Classloaders.bsh
    deploy/snmp-adaptor.sar/managers.xml
    deploy/snmp-adaptor.sar/META-INF/jboss-service.xml
    deploy-hasingleton/jms/uil2-service.xml
    Eliminare il file iiop-service.xml dalla directory deploy di uno dei due server (da verificare se crea problemi)

    Rispondi
  • 12. Tommy  |  aprile 24, 2007 alle 11:07 am

    per il cambiamento delle porte c’è il binding manager….;-)

    Rispondi
  • 13. Cristian  |  novembre 13, 2007 alle 1:16 PM

    Ciao ho letto il tuo post. Complimenti lavoro interessante.
    Non ho mai realizzato cluster … ma vorrei farlo. Mi chiedevo se sai spiegarmi la differenza nell’utilizzare la tecnologia JBOSS per il clustering java rispetto a XEN . La risposta è solo quella ovvia xen è utile in sistemi cluster generici , non specifici j2ee?
    A livello di programmazione (non parlo di configurazioni varie ed deployment)…. ho visto ke basta aggiungere annotiation clustered per rendere un EJB clusterizzabili. Basta effettivamente solo quello ?

    Rispondi
  • 14. Francesco  |  luglio 8, 2008 alle 10:11 am

    Ciao, complimenti per il bellissimo post.
    Non mi torna una cosa, dalla documentazione ufficiale ho letto che gli MDB possono essere deployati su tutti i nodi per far bilanciamento di carico. In pratica far si che più messaggi sulla coda jms, per bilanciare il carico, vengono processati da diversi MDB.
    Forse ho capito male io, mi aiuteresti a capire se quello che ho detto si può fare?
    Grazie
    Francesco

    Rispondi
  • 15. Charis  |  aprile 18, 2013 alle 12:17 am

    What’s up to every , because I am in fact eager of reading this web site’s post to be updated on a regular
    basis. It consists of fastidious material.

    Rispondi
  • 16. Trinity  |  gennaio 16, 2014 alle 9:40 am

    I am just trying to write a review and getting information was harder than i thought it would be

    Rispondi

Lascia un commento

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendario

ottobre: 2006
L M M G V S D
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Most Recent Posts