CERCA SITEMAP FEED RSS 1280
Ultimo aggiornamento: 30 Agosto 2009

JBoss Messaging

JBoss Messaging è un provider Java Messaging Service ad alte prestazioni che introduce diversi miglioramenti rispetto a JBossMQ il provider JMS presente in JBoss AS 4.

JBoss Messaging è completamente compatibile con le specifiche Sun JMS 1.1 e consta essenzialmente di due parti:
  • JBoss Messaging Core: un sistema di trasporto di messaggi transazionale e affidabile
  • JMS Facade: una collezione di classi e file di configurazione che aggiungono al Core un’interfaccia JMS 1.1 compatibile.
Altre caratteristiche di JBoss Messaging includono:
  • modelli publich-subscrive e point-to-point
  • messaggi persistenti e non
  • garanzia di consegna dei messaggi che assicura che i messaggi arrivino una e una sola volta
  • supporto della semantica ACID (transazioni)
  • personalizzazione della sicurezza basata su JAAS
Inoltre dal momento che JBoss Messaging è compatibile con JMS 1.1 e 1.0.2b, qualsiasi codice scritto per JBossMQ funzionerà correttamente anche su JBoss Messaging senza alcun cambiamento.

Configurazione di JBoss Messaging

Le JMS API definiscono come i client interagiscono col server ma l’esatta definizione e implementazione del servizio di messaging dipendono dal provider.
La configurazione di JBoss Messaging avviene mediante diversi file di configurazione: messaging-service.xml, remoting-service.xml, xxx-persistence-service.xml. connection-factories-service.xml e destination-service.xml
Il cuore di JBoss Messaging è il Server Peer, la cui configurazione (insieme a quella di diversi plugin quali ThreadPool e MessageStore) risiede nel file di configurazione messaging-service.xml.

Un esempio di configurazione del Server Peer è il seguente:
<mbean code="org.jboss.jms.server.ServerPeer" name="jboss.messaging:service=ServerPeer" xmbean-dd="xmdesc/ServerPeer-xmbean.xml">
  <constructor>
    <!-- ServerPeerID -->
    <arg type="java.lang.String" value="server.0"/>
    <!-- DefaultQueueJNDIContext -->
    <arg type="java.lang.String" value="/queue"/>
    <!-- DefaultTopicJNDIContext -->
    <arg type="java.lang.String" value="/topic"/>
  </constructor>

  <depends optional-attribute-name="ThreadPool">jboss.messaging:service=ThreadPool</depends>
  <depends optional-attribute-name="PersistenceManager">jboss.messaging:service=PersistenceManager</depends>
  <depends optional-attribute-name="MessageStore">jboss.messaging:service=MessageStore</depends>
  <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>

  <!-- Set to -1 to completely disable client leasing -->
  <attribute name="SecurityDomain">java:/jaas/messaging</attribute>
  <attribute name="DefaultSecurityConfig">
    <security>
      <role name="guest" read="true" write="true" create="true"/>
    </security>
  </attribute>
</mbean>
L’elemento attribute con name SecurityDomain viene usato quando JBoss Messaging autentica e autorizza l’accesso alle destinazioni JMS per la lettura, la scrittura o la creazione.
Deve pertanto corrispondere ad una entry definita nel file login-config.xml, che è configurata esattamente come qualsiasi altro security domain in JBoss.
L’elemento attribute con name DefaultSecurityConfig viene usato la configurazione di sicurezza per una particolare coda o topic non è stata sovrascritta nel deployment descriptor delle destinazioni.
Tale elemento contiene un elemento security che contiene elementi role multipli.
Ogni elemento role definisce l’accesso per un particolare ruolo: se l’attributo read è true allora di default il ruolo ha accesso in lettura alle destinazioni e può quindi creare consumer e ricevere messaggi, se l’attributo write è true allora ha accesso in scrittura e può creare producer e inviare messaggi, se l’attributo create è posto a true può creare durable subscription.

Configurare il Persistence Store

JBoss Messaging interagisce con il sistema di memorizzazione attraverso due servizi: il Persistence Manager e il Channel Mapper.
Il Persistence Manager è usato per gestire le funzioni relative ai messaggi mentre il Channel Mapper per gestire i dati persistenti relativi alle destinazioni.
JBoss Messaging fa uso di un Persistence Manager JDBC che gestisce la persistenza dei messaggi attraverso un database relazionale accessibile mediante JDBC: dal momento che il Persistence Manager è pluggable è possibile sostituirlo con altre impleentazioni (che ad esempio utilizzano altre forme di memorizzazione).
La configurazione del servizio di persistenza avviene mediatne il file xxx-persistence-service.xml: di default si fa uso di un database Hypersonic e quindi del file hsqldb-persistence-service.xml
Nella cartella docs/examples/jms sono comunque disponibili i file di configurazione per database esterni come MySQL, Oracle, PostgreSQL ...

La configurazione del Persistence Manager per MySQL è ad esempio la seguente:
<server>
  <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManager" name="jboss.messaging:service=PersistenceManager" xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
    <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
    <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
    <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
    <attribute name="DataSource">java:/DefaultDS</attribute>
    <attribute name="CreateTablesOnStartup">true</attribute>
    <attribute name="UsingBatchUpdates">true</attribute>
    <attribute name="SqlProperties"><![CDATA[
CREATE_MESSAGE_REF=CREATE TABLE JMS_MESSAGE_REFERENCE (CHANNELID BIGINT, MESSAGEID BIGINT, TRANSACTIONID BIGINT, STATE CHAR(1), ORD BIGINT, DELIVERYCOUNT INTEGER, RELIABLE CHAR(1), LOADED CHAR(1), PRIMARY KEY(CHANNELID, MESSAGEID))
CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JMS_MESSAGE_REF_TX ON JMS_MESSAGE_REFERENCE (TRANSACTIONID)
CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JMS_MESSAGE_REF_ORD ON JMS_MESSAGE_REFERENCE (ORD)
CREATE_IDX_MESSAGE_REF_MESSAGEID=CREATE INDEX JMS_MESSAGE_REF_MESSAGEID ON JMS_MESSAGE_REFERENCE (MESSAGEID)
CREATE_IDX_MESSAGE_REF_LOADED=CREATE INDEX JMS_MESSAGE_REF_LOADED ON JMS_MESSAGE_REFERENCE (LOADED)
CREATE_IDX_MESSAGE_REF_RELIABLE=CREATE INDEX JMS_MESSAGE_REF_RELIABLE ON JMS_MESSAGE_REFERENCE (RELIABLE)
INSERT_MESSAGE_REF=INSERT INTO JMS_MESSAGE_REFERENCE (CHANNELID, MESSAGEID, TRANSACTIONID, STATE, ORD, DELIVERYCOUNT, RELIABLE, LOADED) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
....      ]]>
    </attribute>
    <attribute name="MaxParams">500</attribute>
  </mbean>

  <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper" name="jboss.messaging:service=ChannelMapper" xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
    <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
    <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
    <attribute name="DataSource">java:/DefaultDS</attribute>
    <attribute name="SqlProperties"><![CDATA[
CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USERID))
CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
....
      ]]>
    </attribute>
  </mbean>
</server>
Per cambiare database è quindi sufficiente sostituire il file hsqldb-persistence-service.xml con il file di configurazione del database che si vuole utilizzare e riavviare il server.
Inoltre di default il Messaging Service fa riferimento al datasource java:/DefaultDS, se si sta utilizzando un datasource con un nome JNDI differente occorre aggiornare tutti gli attributi DataSource nel file di configurazione della persistenza.
Settando a true l’attributo CreateTableOnStartup il persistence manager crea le tabelle e gli indici necessari quando viene avviato: se le tabelle esistono già viene prodotta uan SQLEXception che verrà ignorata dal Persistence Manager.

Configurare le destinazioni

Quando viene installato JBoss Messaging ha un insieme di destinazioni preconfigurate definite nel file destinations-service.xml
<mbean code="org.jboss.jms.server.destination.Queue" name="jboss.messaging.destination:service=Queue,name=DLQ" xmbean-dd="xmdesc/Queue-xmbean.xml">
  <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
</mbean>

<mbean code="org.jboss.jms.server.destination.Topic" name="jboss.messaging.destination:service=Topic,name=testTopic" xmbean-dd="xmdesc/Topic-xmbean.xml">
  <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
  <attribute name="SecurityConfig">
    <security>
      <role name="guest" read="true" write="true"/>
      <role name="publisher" read="true" write="true" create="false"/>
      <role name="durpublisher" read="true" write="true" create="true"/>
    </security>
  </attribute>
</mbean>

<mbean code="org.jboss.jms.server.destination.Queue" name="jboss.messaging.destination:service=Queue,name=testQueue" xmbean-dd="xmdesc/Queue-xmbean.xml">
  <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
  <attribute name="SecurityConfig">
    <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>
L’attributo SecurityConfig permette di specificare quali ruoli hanno accesso alla destinazione in lettura (read), scrittura (write) e creazione (create).
Tali impostazioni sovrascrivono quelle di default nel file messaging-service.xml. Per definire una nuova destinazione occorre creare un nuovo deployment descriptor chiamato *-service.xml e copiarlo nella cartella di deploy.
<?xml version="1.0" encoding="UTF-8"?>
<server>
  <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
    <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
  </loader-repository>
  <mbean code="org.jboss.jms.server.destination.Queue" name="jboss.messaging.destination:service=Queue,name=testQueue" xmbean-dd="xmdesc/Queue-xmbean.xml">
    <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
    <attribute name="SecurityConfig">
      <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>
    <attribute name="fullSize">75000</attribute>
    <attribute name="pageSize">2000</attribute>
    <attribute name="downCacheSize">2000</attribute>
  </mbean>
</server>
Una nuova ed importante caratteristica di JBoss Messaging sono i Pageable Channels.
Se un’applicazione deve supportare code molto grandi o sottoscrizioni contenenti milioni di messaggi allora non è possibile memorizzarli tutti.
JBoss Messaging risolve questo problema permettendo di specificare il massimo numero di messaggi che possono essere memorizzati in memoria coda per coda o topic per topic.
  • fullSize: rappresenta il massimo numero di messaggi amntenuti in una coda o topic.
  • pageSize: rappresenta il massimo numero di messaggi precaricati a seguito di un’operazione.
  • downCacheSize – quando i messaggi vengono memorizzati essi prima finiscono in una Down Cache in maniera tale da poterli memorizzare con una singola operazione e quindi migliorare le prestazioni.
Questo parametro determina pertanto la dimensione della Down Cache e quindi il numero massimo di messaggi che questa può memorizzare prima che questi vengano trasferiti nel database.

Configurare ConnectionFactory

Di defualt JBoss Messaging effettua il binding di una connection factory ai seguenti JNDI context: /ConnectionFactory, /XAConnectionFactory, java:/ConnectionFactory, java:/XAConnectionFactory
E’ possibile comunque aggiurngere connection factory aggiungendo nuovi Mbean ConnectionFactory nel file connection-factories-service.xml o definendo interamente un nuovo servizio mediante un deployment descriptor *-service.xml posto nella directory deploy.
<?xml version="1.0" encoding="UTF-8"?>
<server>
  <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
    <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
  </loader-repository>
  <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory" name="jboss.messaging.destination:service=ConnectionFactory" xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
    <constructor>
      <arg type="java.lang.String" value="myClientID"/>
    </constructor>
    <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
    <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=socket</depends>
    <attribute name="PrefetchSize">10</attribute>
    <attribute name="DefaultTempQueueFullSize">1000</attribute>
    <attribute name="DefaultTempQueuePageSize">50</attribute>
    <attribute name="DefaultTempQueueDownCacheSize">50</attribute>
    <attribute name="JNDIBindings">
      <bindings>
        <binding>/MyConnectionFactory1</binding>
        <binding>/factories/cf1</binding>>
      </bindings>
    </attribute>
  </mbean>
</server>
Il precedente esempio crea una connection factory con client ID preconfigurato e lo collega /MyConnectionFactory e /factories/cf
PrefetchSize è un attributo opzionale che determina quanti messaggi il consumer lato client memorizzerà localmente evitanto in tal modo al client di comunicare col server per ogni messaggio ricevuto.
DefaultTempQueueFullSize, DefaultTempQueuePageSize, DefaultTempQueueDownCacheSize sono attributi opzionali che determinano i parametri di paging di default.