4 Replies Latest reply on Mar 23, 2005 11:22 AM by Adrian Caraiman

    MDB performance

    Adrian Caraiman Newbie

      Hello,

      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");
      }



        • 1. Re: MDB performance
          Adrian Brock Master

           

          DELETE FROM JMS_MESSAGES WHERE TXID=1410 AND TXOP='D
          which needs more than a minute to complete !
          


          So the query is not supported by a db index? Talk to your DBA.

          • 2. Re: MDB performance
            Adrian Caraiman Newbie

            Thanks, adrian.
            we build in the suggested index and this made indeed the mgs delivery faster.. but still not fast enough :(
            The MDB waiting time was reduced 1:20 min to smth about 1 sec, which is yet too long (the msg-producer is verry fast).
            I tried to not use transaction, as i instructed the JMSProviderLoader to work with ConnectionFactory instead of XA...

            < attribute name="TopicFactoryRef">ConnectionFactory < /attribute>

            but it didn't increased the delivery speed.
            Is there a way to make the MDB work as quick as a clasical msg listener ?

            any idea would be appreciated !

            • 3. Re: MDB performance
              Adrian Brock Master

              An MDB should be faster than a classical message listener
              unless you deploy it as singleton, like you have done:

              <MinimumSize>1</MinimumSize>
              <MaximumSize>1</MaximumSize>
              


              I have no idea on your other problem without seeing some performance info
              (P.S. I don't mean "it takes about second", because you haven't identified "IT")

              • 4. Re: MDB performance
                Adrian Caraiman Newbie

                you had right, adrian.

                'IT' was a stupid logging issue, that tricked me showing that waiting time was in remote jboss. on another logging level i discovered that this time (about 2 sec) was spent commiting data in the destination db. Quite stupid, but that is, when the project grows, the details aren't obvious anymore..

                the other issue (Singleton) is still open, there are db deadlock problems when parallel MDBs are running.

                thanx anyway !