205 lines
7.8 KiB
HTML
205 lines
7.8 KiB
HTML
<!--
|
|
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>
|