MDB performance
acaraiman Mar 10, 2005 7:36 AMHello,
I am experiencing a performance problem when using durable-subscribed MDBs. Becouse there were a partially network failure, the clients couldn't consume their durable-messages, wich rised the number of messages by about 10000 / subscription.
When the network worked again, i noticed that remote subscribed MDB become verry slow with consuming:
client-side log:
first message:
12:22:23,405 INFO [ItemsPersister] Starting to process and save 50 items
12:22:23,632 INFO [ItemsPersister] Items processed and saved
(message processed)
-------------
in this time the JBoss which hosts the ItemsTopic (JBoss 4.0.0) does an intensive db operation (mysql 4.1.7):
DELETE FROM JMS_MESSAGES WHERE TXID=1410 AND TXOP='D
which needs more than a minute to complete !
-------------
next message:
12:23:46,496 INFO [ItemsPersister] Starting to process and save 50 items
(here is the onMessage() method which completes draughty)
12:23:46,694 INFO [ItemsPersister] Items processed and saved
Anyway in the same circumstances a classical JMS-listener client (no MDB) consummed paralelly his same set of messages from the same Topic in less than 10 minutes !
Is this caused by any wrongly configured parameter like acknowledge mode or something in my code ? (code & configurations follows)
Thaks in advance.
ejb-jar.xml ---------- <ejb-jar > <description>[CDATA[No Description.]]</description> <display-name>Generated by XDoclet</display-name> <enterprise-beans> <!-- Message Driven Beans --> <message-driven > <description>[CDATA[]]</description> <ejb-name>ItemChangesBean</ejb-name> <ejb-class>de.mueller.provider.items2provider.ItemChangesBean</ejb-class> <transaction-type>Bean</transaction-type> <acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode> <message-driven-destination> <destination-type>javax.jms.Topic</destination-type> <subscription-durability>Durable</subscription-durability> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar> jboss.xml --------- <jboss> <enterprise-beans> <!-- To add beans that you have deployment descriptor info for, add a file to your XDoclet merge directory called jboss-beans.xml that contains the <session></session>, <entity></entity> and <message-driven></message-driven> markup for those beans. --> <message-driven> <ejb-name>ItemChangesBean</ejb-name> <destination-jndi-name>topic/Items</destination-jndi-name> <mdb-client-id>ItemChangesBean1</mdb-client-id> <mdb-subscription-id>ItemChangesBean</mdb-subscription-id> <configuration-name>Singleton Message Driven Bean</configuration-name> <invoker-bindings> <invoker> <invoker-proxy-binding-name>remote-JMS-invoker</invoker-proxy-binding-name> </invoker> </invoker-bindings> </message-driven> </enterprise-beans> <resource-managers> </resource-managers> <invoker-proxy-bindings> <invoker-proxy-binding> <name>remote-JMS-invoker</name> <invoker-mbean>default</invoker-mbean> <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory> <proxy-factory-config> <JMSProviderAdapterJNDI>RemoteJMSProvider</JMSProviderAdapterJNDI> <ServerSessionPoolFactoryJNDI>RemoteJMSPool</ServerSessionPoolFactoryJNDI> <MinimumSize>1</MinimumSize> <MaximumSize>1</MaximumSize> <KeepAliveMillis>30000</KeepAliveMillis> <MaxMessages>1</MaxMessages> <MDBConfig> <ReconnectIntervalSec>10</ReconnectIntervalSec> <!--DLQConfig> <DestinationQueue>queue/DLQ</DestinationQueue> <MaxTimesRedelivered>10</MaxTimesRedelivered> <TimeToLive>0</TimeToLive> </DLQConfig--> </MDBConfig> </proxy-factory-config> </invoker-proxy-binding> </invoker-proxy-bindings> </jboss> remoteJMS-ds.xml ------------------------ <!-- ==================================================================== --> <!-- JMS Stuff --> <!-- ==================================================================== --> <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.mq:service=JMSProviderLoader,name=RemoteJMSProvider"> <attribute name="ProviderName">RemoteJMSProvider</attribute> <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute> <!-- The combined connection factory --> <attribute name="FactoryRef">XAConnectionFactory</attribute> <!-- The queue connection factory --> <attribute name="QueueFactoryRef">XAConnectionFactory</attribute> <!-- The topic factory --> <attribute name="TopicFactoryRef">XAConnectionFactory</attribute> <attribute name="Properties"> java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=10.222.2.13:1099 <!-- when using clustering you give the list of members in the cluster here; JNDI port is 1100 then --> <!-- java.naming.provider.url=server1:1100,server2:1100 --> </attribute> </mbean> <!-- The server session pool for Message Driven Beans --> <mbean code="org.jboss.jms.asf.ServerSessionPoolLoader" name="jboss.mq:service=ServerSessionPoolMBean,name=RemoteJMSPool"> <depends optional-attribute-name="XidFactory">jboss:service=XidFactory</depends> <attribute name="PoolName">RemoteJMSPool</attribute> <attribute name="PoolFactoryClass"> org.jboss.jms.asf.StdServerSessionPoolFactory </attribute> </mbean>
ChangesBean.java - onMessage()
----------------
public void onMessage(Message message) {
logger.debug("Processing WWS changes message");
BytesMessage bm = (BytesMessage) message;
byte bytes[] = null;
try {
bytes = WWSMessageSupport.getBytes(bm);
Persister persister = createPersister(bytes);
if (persister == null) {
return;
}
try {
logger.debug("Beginning persister transaction");
persister.beginTransaction();
persister.persist();
persister.commit();
logger.debug("Commited persister transaction");
} finally {
if (persister != null) {
try {
persister.rollback();
} catch (SystemException ex) {
// Ignore it
}
try {
persister.close();
} catch (HibernateException ex) {
// Ignore it
} catch (SystemException ex) {
// Ignore it
}
}
}
} catch (Throwable t) {
logger.error("Unable to process WWS changes message", t);
try {
logger.error("Unprocessed WWS changes message id is " + WWSMessageSupport.getMessageId(message));
} catch (Throwable idEx) {
logger.debug("Unable to get unprocessed WWS changes message id", idEx);
}
if (bytes != null) {
logger.info("Unprocessed WWS changes message is " + new String(bytes));
}
throw new MessageProcessingException(t);
}
logger.debug("WWS changes message processed");
}
public void persist() throws HibernateException {
logger.info("Starting to process and save " + wwsItems.size() + " items");
deleteRelations(wwsItems, session);
for (Iterator it = wwsItems.iterator(); it.hasNext();) {
Item i = (Item) it.next();
saveItem(i, session);
}
logger.info("Items processed and saved");
}