mirror of
https://github.com/apache/activemq-artemis.git
synced 2025-02-28 06:19:21 +00:00
https://issues.apache.org/jira/browse/ACTIVEMQ6-4 rename all the config files to activemq and fix schema names in them
<html> <head> <title>HornetQ No Consumer Buffering Example</title> <link rel="stylesheet" type="text/css" href="../common/common.css" /> <link rel="stylesheet" type="text/css" href="../common/prettify.css" /> <script type="text/javascript" src="../common/prettify.js"></script> </head> <body onload="prettyPrint()"> <h1>No Consumer Buffering Example</h1> <p>By default, HornetQ consumers buffer messages from the server in a client side buffer before actual delivery actually occurs.</p> <p>This improves performance since otherwise every time you called receive() or had processed the last message in a MessageListener onMessage() method, the HornetQ client would have to go the server to request the next message involving a network round trip for every message reducing performance.</p> <p>Therefore, by default, HornetQ pre-fetches messages into a buffer on each consumer. The total maximum size of messages in bytes that will be buffered on each consumer is determined by the <code>consumer-window-size</code> parameter on the connection factory.</p> <p>In some cases it is not desirable to buffer any messages on the client side consumer.</p> <p>An example would be an order queue which had multiple consumers that processed orders from the queue. Each order takes a significant time to process, but each one should be processed in a timely fashion.</p> <p>If orders were buffered in each consumer, and a new consumer was added that consumer would not be able to process orders which were already in the client side buffer of another consumer.</p> <p>To turn off client side buffering of messages, set <code>consumer-window-size</code> to zero.</p> <p>With HornetQ you can specify a maximum consume rate at which a JMS MessageConsumer will consume messages. This can be specified when creating or deploying the connection factory. See <code>hornetq-jms.xml</code></p> <h2>Example step-by-step</h2> <p>In this example we specify a <code>consumer-window-size</code> of <code>0</code> bytes in the <code>hornetq-jms.xml</code> file when deploying the connection factory:</p> <pre class="prettyprint"> <code> <connection-factory name="ConnectionFactory"> <connector-ref connector-name="netty-connector"/> <entries> <entry name="ConnectionFactory"/> </entries> <!-- We set the consumer window size to 0, which means messages are not buffered at all on the client side --> <consumer-window-size>0</consumer-window-size> </connection-factory> </code> </pre> <p>We create a consumer on a queue and send 10 messages to it. We then create another consumer on the same queue.</p> <p>We then consume messages from each consumer in a semi-random order. We note that the messages are consumed in the order they were sent.</p> <p>If the messages had been buffered in each consumer they would not be available to be consumed in an order determined afer delivery.</p> <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p> <ol> <li>Create an initial context to perform the JNDI lookup.</li> <pre class="prettyprint"> <code>initialContext = getContext(0);</code> </pre> <li>Perfom a lookup on the queue</li> <pre class="prettyprint"> <code>Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");</code> </pre> <li>Perform a lookup on the Connection Factory</li> <pre class="prettyprint"> <code>ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code> </pre> <li>Create a JMS Connection</li> <pre class="prettyprint"> <code>connection = cf.createConnection();</code> </pre> <li>Create a JMS Session</li> <pre class="prettyprint"> <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code> </pre> <li>Create a JMS MessageProducer</li> <pre class="prettyprint"> <code>MessageProducer producer = session.createProducer(queue);</code> </pre> <li>Create a JMS MessageConsumer</li> <pre class="prettyprint"> <code>MessageConsumer consumer1 = session.createConsumer(queue);</code> </pre> <li>Start the connection</li> <pre class="prettyprint"> <code> connection.start(); </code> </pre> <li>Send 10 messages to the queue</li> <pre class="prettyprint"> <code> final int numMessages = 10; for (int i = 0; i < numMessages; i++) { TextMessage message = session.createTextMessage("This is text message: " + i); producer.send(message); } </code> </pre> <li>Create another JMS MessageConsumer on the same queue.</li> <pre class="prettyprint"> <code>MessageConsumer consumer2 = session.createConsumer(queue);</code> </pre> <li>Consume three messages from consumer2</li> <pre class="prettyprint"> <code> for (int i = 0; i < 3; i++) { TextMessage message = (TextMessage)consumer2.receive(2000); System.out.println("Consumed message from consumer2: " + message.getText()); } </code> </pre> <li>Consume five messages from consumer1</li> <pre class="prettyprint"> <code> for (int i = 0; i < 5; i++) { TextMessage message = (TextMessage)consumer1.receive(2000); System.out.println("Consumed message from consumer1: " + message.getText()); } </code> </pre> <li>Consume two more messages from consumer2</li> <pre class="prettyprint"> <code> for (int i = 0; i < 2; i++) { TextMessage message = (TextMessage)consumer1.receive(2000); System.out.println("Consumed message from consumer2: " + message.getText()); } </code> </pre> <li>Be sure to close our resources!</li> <pre class="prettyprint"> <code> finally { if (initialContext != null) { initialContext.close(); } if (connection != null) { connection.close(); } }</code> </pre> </ol> <h2>More information</h2> <ul> <li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#flow-control.consumer.window">Consumer Window-Based Flow Control chapter</a></li> </ul> </body> </html>