mirror of
https://github.com/apache/activemq-artemis.git
synced 2025-02-06 18:18:43 +00:00
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <html> <head> <title>ActiveMQ Artemis 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, ActiveMQ Artemis 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 ActiveMQ Artemis 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, ActiveMQ Artemis 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 ActiveMQ Artemis 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>activemq-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>activemq-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 -Pexample</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>