[jboss-cvs] JBoss Messaging SVN: r6486 - in trunk/examples/jms/message-counters: server0 and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Apr 20 05:20:05 EDT 2009


Author: jmesnil
Date: 2009-04-20 05:20:04 -0400 (Mon, 20 Apr 2009)
New Revision: 6486

Modified:
   trunk/examples/jms/message-counters/readme.html
   trunk/examples/jms/message-counters/server0/jbm-configuration.xml
   trunk/examples/jms/message-counters/src/org/jboss/jms/example/MessageCounterExample.java
Log:
MessageCounter Example

* readme + code comment

Modified: trunk/examples/jms/message-counters/readme.html
===================================================================
--- trunk/examples/jms/message-counters/readme.html	2009-04-18 13:43:37 UTC (rev 6485)
+++ trunk/examples/jms/message-counters/readme.html	2009-04-20 09:20:04 UTC (rev 6486)
@@ -1,41 +1,30 @@
 <html>
   <head>
-    <title>JBoss Messaging Expiration Example</title>
+    <title>JBoss Messaging Message Counter Example</title>
     <link rel="stylesheet" type="text/css" href="../common/common.css">
   </head>
   <body>
-     <h1>JMS Expiration Example</h1>
+     <h1>JMS Message Counter Example</h1>
 
-     <p>This example shows you how to define and deal with message expiration.</p>
-     <p>Messages can be retained in the messaging system for a limited period of time before being removed.
-         JMS specification states that clients should not receive messages that have been expired (but it does not guarantee this will not happen).</p>
-     <p>JBoss Messaging can assign a <em>expiry destination</em> to a given queue so that when messages are expired, they are removed from the queue and sent
-         to the expiry destination. These "expired" messages can later be consumed from the expiry destination for further inspection.
-     <p>
-         The example will send 1 message with a short <em>time-to-live</em> to a queue. We will wait for the message to expire and checks that the message
-         is no longer in the queue it was sent to.
-         We will instead consume it from an <em>expiry queue</em> where it was moved when it expired.
+     <p>This example shows you how to use message counters to have information on a JMS queue.</p>
+     <p>The example will show how to configure sampling of message counters.<br />
+         We will produce and consume 1 message from a queue. Interleaved with the JMS operation, we will retrieve the queue's message counters
+         at different times to display the metrics on the queue.
      </p>
      <h2>Example setup</h2>
-     <p>Expiry destinations are defined as in the queue settings configuration file <a href="server0/jbm-queues.xml">jbm-queues.xml</a>:</p>
+     <p>Message counter is configured in the server configuration file <a href="server0/jbm-configuration.xml">jbm-queues.xml</a>:</p>
      <pre>
-         <code>&lt;address-settings match="jms.queue.exampleQueue"&gt;
-            &lt;expiry-address&gt;jms.queue.expiryQueue&lt;/expiry-address&gt;
-         &lt;/address-settings&gt;
-         </code>
-     </pre>          
-     <p>This configuration will moved expired messages from the <code>exampleQueue</code> to the <code>expiryQueue</code></p>
-     <p>JBoss Messaging allows to specify either a <code>Queue</code> by prefixing the <code>expiry-address</code> with <code>jms.queue.</code>
-         or a <code>Topic</code> by prefixing with <code>jms.topic.</code>.<br />
-         In this example, we will use a <code>Queue</code> to hold the expired messages.</p>
-     <p>Since we want to consume messages from this expiryQueue, we also need to add a JNDI binding to perform a lookup.
-         This is configured in <a href="server0/jbm-jms.xml">jbm-jms.xml</a></p>
-     <pre>
-         <code>&lt;queue name="expiryQueue"&gt;
-            &lt;entry name="/queue/expiryQueue"/&gt;
-         &lt;/queue&gt;</code>
+         <code>&lt;message-counter-enabled&gt;true&lt;/message-counter-enabled&gt;
+         &lt;message-counter-sample-period&gt;2000&lt;/message-counter-sample-period&gt;
+         &lt;message-counter-max-day-history&gt;2&lt;/message-counter-max-day-history&gt;</code>
      </pre>
-     </p>
+     <p>By default, Message counter is not enabled (for performance reason). To enable them, set <code>message-counter-enabled</code> to <code>true</code>.<br />
+     Queues are sampled every 10 seconds by default. For this example we will reduce it to 2 seconds by setting <code>message-counter-sample-period</code> to <code>2000</code>.<br />
+     JBoss Messaging holds in memory the message counters' history for a maximum number of days (10 by default). We can change the number of days the history is kept by setting
+         the <code>message-counter-max-day-history</code> parameter.</p>
+     <p>The sample period and the max day history parameters have an small impact on the performance of JBoss Messaging (the resources taken to sample a queue are not available to the system's
+         normal use). You should set these parameters accordingly to the use and throughput of your messages.</p>
+         
      <h2>Example step-by-step</h2>
      <p><i>To run the example, simply type <code>ant</code> from this directory</i></p>
      <ol>
@@ -54,108 +43,110 @@
            <code>ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");</code>
         </pre>
 
-        <li>We create a JMS connection</li>
+        <li>We create a JMS connection, session and producer for the queue</li>
         <pre>
-           <code>connection = cf.createConnection();</code>
-        </pre>
-
-        <li>We create a JMS session. The session is created as non transacted and will auto acknowledge messages</li>
-        <pre>
-           <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code>
-        </pre>
-
-        <li>We create a JMS message producer on the session. This will be used to send the messages</li>
-        <pre>
-          <code>MessageProducer messageProducer = session.createProducer(topic);</code>
+           <code> connection = cf.createQueueConnection();
+            QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+            MessageProducer producer = session.createProducer(queue);</code>
        </pre>
        
-       <li>Messages sent by this producer will be retained for 1s (1000ms) before expiration</li>
-       <pre>
-           <code>producer.setTimeToLive(1000);</code>
-       </pre>
-
-        <li>We create a text messages</li>
+        <li>We create and send a JMS text message</li>
         <pre>
-            <code>TextMessage message = session.createTextMessage("this is a text message");</code>
+            <code>TextMessage message = session.createTextMessage("This is a text message");
+            producer.send(message);
+            System.out.println("Sent message: " + message.getText());</code>
         </pre>
 
-        <li>We send the message to the queue</li>
+        <li>We will now sleep a little bit to be sure the queue is sample. Since we have configure the sample period to be 2 seconds,
+            we will sleep for 3 seconds to be sure that a sample is taken</li>
         <pre>
-            <code>producer.send(message);</code>
+            <code>System.out.println("Sleep a little bit to have the queue sampled...");
+            Thread.sleep(3000);</code>
         </pre>
         
-       <li>We sleep a little bit to let the message expire</li>
+        <p>We now need to retrieve the message counters. They're available from the JMS Queue management resource. In this example, we
+            will retrieve them using JMX (see the <a href="../jmx/readme.html">JMX example</a> for a more complete description). You can also use JMS message to retrieve them (see the <a href="../management/readme.html">Management example</a> to
+            learn about managing JBoss Messaging using JMS messages).</p>
+
+       <li>We retrieve the JMX MBean used to manage the JMS queue</li>
         <pre>
-            <code>Thread.sleep(5000);</code>
+            <code>ObjectName on = ObjectNames.getJMSQueueObjectName(queue.getQueueName());
+            JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), new HashMap());
+            MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+            JMSQueueControlMBean queueControl = (JMSQueueControlMBean)MBeanServerInvocationHandler.newProxyInstance(mbsc,
+                                                                                                        on,
+                                                                                                        JMSQueueControlMBean.class,
+                                                                                                        false);</code>
         </pre>
 
-        <p>We will now try to consume the message from the queue but it won't be there since it has expired</p>
-
-        <li>We create a JMS message consumer on the queue</li>
+        <li>We retrieve the message counter and display them. MessageCounters are retrieved as <code>CompositeData</code> for portability reason (wether
+            JMX is used for management or JMS messages). To make it simpler to use them in the code, there is a <code>MessageCounterInfo</code> data structure.</li>
         <pre>
-            <code>MessageConsumer messageConsumer = session.createConsumer(queue);</code>
+            <code>CompositeData compositeData = queueControl.listMessageCounter();
+            MessageCounterInfo messageCounter = MessageCounterInfo.from(compositeData);</code>>
         </pre>
         
-        <li>We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started</li>
+        <li>We display the message counters</li>
         <pre>
-           <code>connection.start();</code>
+            <code>displayMessageCounter(messageCounter);</code>
         </pre>
-
-        <li>We try to receive a message from the queue. Since there is none, the call will timeout after 5000ms and <code>messageReceived</code> will be <code>null</code>
+        
+        <p>The message counter contains a variety of metrics on the queue which is sampled (total messages added to the queue, current depth of the queue, deltas since the last sample, timestamp
+            of the last message added, timestamp of the last sample, etc.)</p>
         <pre>
-           <code>TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
-           System.out.println("Received message from " + queue.getQueueName() + ": " + messageReceived);</code>
+            <code>private void displayMessageCounter(MessageCounterInfo counter)
+                {
+                   System.out.format("%s (sample updated at %s)\n",  counter.getName(), counter.getUdpateTimestamp());
+                   System.out.format("   %s message(s) added to the queue (since last sample: %s)\n", counter.getCount(), 
+                                                                                                      counter.getCountDelta());
+                   System.out.format("   %s message(s) in the queue (since last sample: %s)\n", counter.getDepth(),
+                                                                                                counter.getDepthDelta());
+                   System.out.format("   last message added at %s\n\n", counter.getLastAddTimestamp());
+                }</code>
         </pre>
-        
-        <p>However, we have configured JBoss Messaging to send any expired messages to the <code>expiryQueue</code>.
-            We will now consume messages from this expiry queue and receives the <em>expired</em> message.</p>
-            
-        <li>We look up the JMS <em>expiry queue</em> object from JNDI</li>
+                
+        <li>We sleep again to have the queue sampled</li>
         <pre>
-           <code>Queue expiryQueue = (Queue)initialContext.lookup("/queue/expiryQueue");</code>
+            <code>System.out.println("Sleep a little bit again...");
+            Thread.sleep(3000);</code>
         </pre>
-                  
-        <li>We create a JMS message consumer on the expiry queue</li>
+        
+        <li>We list the message counters again</li>
         <pre>
-            <code>MessageConsumer expiryConsumer = session.createConsumer(expiryQueue);</code>
+            <code>compositeData = queueControl.listMessageCounter();
+            messageCounter = MessageCounterInfo.from(compositeData);
+            displayMessageCounter(messageCounter);</code>
         </pre>
         
-        <li>We consume a message from the expiry queue:</li>
+        <p>We will now consume a message from the queue before listing a last time the message counters</p>
+        
+        <li>We create a consumer for the queue</li>
         <pre>
-            <code>messageReceived = (TextMessage)expiryConsumer.receive(5000);</code>
+            <code>MessageConsumer consumer = session.createConsumer(queue);</code>
         </pre>
         
-        <li>The message consumed from the <em>expiry queue</em> has the <em>same content</em> than the message which was sent to the <em>queue</em>
+        <li>We start the connection to receive messages on the consumer</li>
         <pre>
-            <code>System.out.println("Received message from " + expiryQueue.getQueueName() + ": " + messageReceived.getText());</code>
-        </pre>    
-            
-        <p>JMS does not specify the notion of expiry queue. From JMS point of view, the message received from the expiry queue
-            is a <strong>different</strong> message than the message expired from the queue: the two messages have the same content (properties and body) but
-            their JMS headers differ.<br />
-            JBoss Messaging defines additional properties to correlate the message received from the expiry queue with the 
-            message expired from the queue</p>
-            
-        <li>The expired message's destination is the expiry queue</li>
-        <pre>
-            <code>System.out.println("Destination of the expired message: " + ((Queue)messageReceived.getJMSDestination()).getQueueName());</code>
+           <code>connection.start();</code>
         </pre>
 
-        <li>The expired message has its own <em>expiration time</em> (its time to live in the <strong>expiry queue</strong>)</li>
+        <li>We receive a message from the queue</li>
         <pre>
-            <code>System.out.println("Expiration time of the expired message (relative to the expiry queue): " + messageReceived.getJMSExpiration());</code>
+           <code>TextMessage messageReceived = (TextMessage)consumer.receive(5000);
+           System.out.format("Received message: %s\n\n", messageReceived.getText());</code>
         </pre>
         
-        <p>As we have not defined a time-to-live for the expiry queue, messages sent to the expiry queue will be kept forever (their JMS Expiration value is 0)</p>
-
-        <li>The <strong>origin destination</strong> is stored in the <code>_JBM_ORIG_DESTINATION</code> property
+        <li>We sleep one last time to have the queue sampled</li>
         <pre>
-            <code>System.out.println("*Origin destination* of the expired message: " + messageReceived.getStringProperty("_JBM_ORIG_DESTINATION"));</code>
+            <code>System.out.println("Sleep a little bit one last time...");
+            Thread.sleep(3000);</code>
         </pre>
-
-        <li>The <strong>actual expiration time</strong> (when the message was expired from the queue) is stored in the <code>_JBM_ACTUAL_EXPIRY</code> property
+        
+        <li>We list the message counters a final time (this time with no message in the queue)</li>
         <pre>
-            <code>System.out.println("*Actual expiration time* of the expired message: " + messageReceived.getLongProperty("_JBM_ACTUAL_EXPIRY"));</code>
+            <code>compositeData = queueControl.listMessageCounter();
+            messageCounter = MessageCounterInfo.from(compositeData);
+            displayMessageCounter(messageCounter);</code>
         </pre>
 
         </p>    
@@ -179,8 +170,7 @@
      <h2>More information</h2>
      
      <ul>
-         <li>Expiry address is <a href="../../../docs/userguide/en/html/configuration.html#configuration.queues">configured on a queue-basis</a></li>
-         <li>Expiry scan period and thread priority are <a href="../../../docs/userguide/en/html/configuration.html#configuration.main">configured at the server level</a></li>
+         <li>Message counter is configured <a href="../../../docs/userguide/en/html/configuration.html#configuration.main">at the server level</a></li>
      </ul>
   </body>
 </html>
\ No newline at end of file

Modified: trunk/examples/jms/message-counters/server0/jbm-configuration.xml
===================================================================
--- trunk/examples/jms/message-counters/server0/jbm-configuration.xml	2009-04-18 13:43:37 UTC (rev 6485)
+++ trunk/examples/jms/message-counters/server0/jbm-configuration.xml	2009-04-20 09:20:04 UTC (rev 6486)
@@ -5,7 +5,7 @@
 
       <jmx-management-enabled>true</jmx-management-enabled>
       <message-counter-enabled>true</message-counter-enabled>
-      <message-counter-sample-period>10000</message-counter-sample-period>
+      <message-counter-sample-period>2000</message-counter-sample-period>
       <message-counter-max-day-history>2</message-counter-max-day-history>
 
       <!-- Connectors -->

Modified: trunk/examples/jms/message-counters/src/org/jboss/jms/example/MessageCounterExample.java
===================================================================
--- trunk/examples/jms/message-counters/src/org/jboss/jms/example/MessageCounterExample.java	2009-04-18 13:43:37 UTC (rev 6485)
+++ trunk/examples/jms/message-counters/src/org/jboss/jms/example/MessageCounterExample.java	2009-04-20 09:20:04 UTC (rev 6486)
@@ -83,14 +83,16 @@
          QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          MessageProducer producer = session.createProducer(queue);
 
-         // Step 7. Create and send a Text Message
+         // Step 5. Create and send a Text Message
          TextMessage message = session.createTextMessage("This is a text message");
          producer.send(message);
          System.out.println("Sent message: " + message.getText());
 
-         System.out.println("Sleep a little bit to have the message counters sampled...");
-         Thread.sleep(12000);
-         
+         // Step 6. Sleep a little bit so that the queue is sampled
+         System.out.println("Sleep a little bit to have the queue sampled...");
+         Thread.sleep(3000);
+
+         // Step 7. Use JMX to retrieve the message counters using the JMSQueueControlMBean
          ObjectName on = ObjectNames.getJMSQueueObjectName(queue.getQueueName());
          JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), new HashMap());
          MBeanServerConnection mbsc = connector.getMBeanServerConnection();
@@ -99,38 +101,46 @@
                                                                                                                  JMSQueueControlMBean.class,
                                                                                                                  false);
 
+         // Step 8. List the message counters and convert them to MessageCounterInfo data structure.
          CompositeData compositeData = queueControl.listMessageCounter();
          MessageCounterInfo messageCounter = MessageCounterInfo.from(compositeData);
+         
+         // Step 9. Display the message counter
          displayMessageCounter(messageCounter);
 
+         // Step 10. Sleep again to have the queue sampled again
          System.out.println("Sleep a little bit again...");
-         Thread.sleep(12000);
-         
+         Thread.sleep(3000);
+
+         // Step 11. List the messages counters again
          compositeData = queueControl.listMessageCounter();
          messageCounter = MessageCounterInfo.from(compositeData);
-
          displayMessageCounter(messageCounter);
 
+         // Step 12. Create a JMS consumer on the queue
          MessageConsumer consumer = session.createConsumer(queue);
          
+         // Step 13. Start the connection to receive messages on the consumer
          connection.start();
          
+         // Step 14. Receive a JMS message from the queue. It corresponds to the message sent at step #5
          TextMessage messageReceived = (TextMessage)consumer.receive(5000);
          System.out.format("Received message: %s\n\n", messageReceived.getText());
+
+         // Step 15. Sleep on last time to have the queue sampled
+         System.out.println("Sleep a little bit one last time...");
+         Thread.sleep(3000);
          
-         System.out.println("Sleep a little bit on last time...");
-         Thread.sleep(12000);
-         
+         // Step 16. Display one last time the message counter
          compositeData = queueControl.listMessageCounter();
          messageCounter = MessageCounterInfo.from(compositeData);
-
          displayMessageCounter(messageCounter);
          
          return true;
       }
       finally
       {
-         // Step 20. Be sure to close our JMS resources!
+         // Step 17. Be sure to close our JMS resources!
          if (initialContext != null)
          {
             initialContext.close();




More information about the jboss-cvs-commits mailing list