Author: buildbot
Date: Fri Sep 16 23:22:09 2016
New Revision: 997547

Log:
Production update by buildbot for activemq

Modified:
    websites/production/activemq/content/cache/main.pageCache
    websites/production/activemq/content/message-groups.html
    websites/production/activemq/content/slow-consumer-handling.html

Modified: websites/production/activemq/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/activemq/content/message-groups.html
==============================================================================
--- websites/production/activemq/content/message-groups.html (original)
+++ websites/production/activemq/content/message-groups.html Fri Sep 16 
23:22:09 2016
@@ -36,6 +36,7 @@
       <link 
href='http://activemq.apache.org/styles/highlighter/styles/shThemeEclipse.css' 
rel='stylesheet' type='text/css' /> 
       <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shCore.js' 
type='text/javascript'></script> 
               <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script> 
+              <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script> 
          
       <script type="text/javascript"> 
         SyntaxHighlighter.defaults['toolbar'] = false; 
@@ -81,120 +82,36 @@
   <tbody>
         <tr>
         <td valign="top" width="100%">
-<div class="wiki-content maincontent"><h2 
id="MessageGroups-MessageGroups">Message Groups</h2>
-
-<p>Message Groups rock! <img class="emoticon emoticon-smile" 
src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/smile.png";
 data-emoticon-name="smile" alt="(smile)"> They are an enhancement to the <a 
shape="rect" href="exclusive-consumer.html">Exclusive Consumer</a> feature to 
provide</p>
-
-<ul><li>guarranteed ordering of the processing of related messages across a 
single queue</li><li>load balancing of the processing of messages across 
multiple consumers</li><li>high availability / auto-failover to other consumers 
if a JVM goes down</li></ul>
-
-
-<p>So logically Message Groups are kinda like a parallel <a shape="rect" 
href="exclusive-consumer.html">Exclusive Consumer</a>. Rather than all messages 
going to a single consumer, the standard JMS header 
<strong>JMSXGroupID</strong> is used to define which <em>message group</em> the 
message belongs to. The Message Group feature then ensures that all messages 
for the same message group will be sent to the same JMS consumer - while that 
consumer stays alive. As soon as the consumer dies another will be chosen.</p>
-
-<p>Another way of explaining Message Groups is that it provides sticky load 
balancing of messages across consumers; where the JMSXGroupID is kinda like a 
HTTP session ID or cookie value and the message broker is acting like a HTTP 
load balancer.</p>
-
-<h3 id="MessageGroups-ExampleUseCase">Example Use Case</h3>
-
-<p>Lets say we are doing some kind of order matching system where people are 
buying and selling things (stocks, shares, placing online bets, whatever).</p>
-
-<p>You want to have consumers who match bids and offers for different items 
(stocks / bets) so they want to keep in RAM for performance a sub-set of the 
data set.</p>
-
-<p>So set the JMSXGroupID to be MSFT, IBM, SUNW and so forth to use the stock 
symbol to define the message group. (It can be any string whatsoever; maybe 
combining trading book, trading exchange, date and so forth - the more specific 
the group ID, the more concurrent you can run).</p>
-
-<p>So assuming we are buying and selling MSFT, IBM, SUNW shares; the Message 
Groups feature guarrentees that all the MSFT messages will be processed in 
order by the same consumer; ditto for IBM and SUNW.</p>
-
-<h3 id="MessageGroups-HowMessageGroupswork">How Message Groups work</h3>
-
-<p>When a message is being dispatched to a consumer, the JMSXGroupID is 
checked. If one is present then the broker checks to see if a consumer owns 
that message group. (Since there could be a massive number of individual 
message groups we use hash buckets rather than the actual JMSXGroupID 
string).</p>
-
-<p>If no consumer is associated with a message group a consumer is chosen. 
That JMS MessageConsumer will receive all further messages with the same 
JMSXGroupID value until</p>
-
-<ul><li>the consumer closes (or the client which created the consumer dies 
etc)</li><li>someone closes the message group by sending a message with a 
negative value for JMSXGroupSeq (see below for more details)</li></ul>
-
-
-<p>Note: like message selector matching, grouping based on JMSXGroupID occurs 
before dispatch on messages in memory. With the default maxPageSize setting, 
large backlogs of messages destined for one group they can block receipt of 
messages to other groups if they don't all fit in memory. You can change the 
default maxPageSize setting for destinations as follows:</p>
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  &lt;destinationPolicy&gt;
-      &lt;policyMap&gt;
-         &lt;policyEntries&gt;
-             &lt;policyEntry queue="&gt;" maxPageSize="1000"/&gt;
-         &lt;/policyEntries&gt;
-      &lt;/policyMap&gt;
-  &lt;/destinationPolicy&gt;</pre>
-</div></div>
-
-<h3 id="MessageGroups-UsingMessageGroups">Using Message Groups</h3>
-
-<p>You just need to change your JMS producers to fill in the 
<strong>JMSXGroupID</strong> message header with some String value of your 
choice. e.g.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-Mesasge message = session.createTextMessage("&lt;foo&gt;hey&lt;/foo&gt;");
+<div class="wiki-content maincontent"><h2 
id="MessageGroups-MessageGroups">Message Groups</h2><p>Message Groups are an 
enhancement to the <a shape="rect" href="exclusive-consumer.html">Exclusive 
Consumer</a> feature. They provide:</p><ul><li>Guaranteed ordering of the 
processing of related messages across a single queue.</li><li>Load balancing of 
the processing of messages across multiple consumers.</li><li>High availability 
/ auto-failover to other consumers if a JVM goes down.</li></ul><p>So logically 
Message Groups are like a parallel <a shape="rect" 
href="exclusive-consumer.html">Exclusive Consumer</a>. Rather than all messages 
going to a single consumer, the standard JMS 
header&#160;<strong><code>JMSXGroupID</code></strong> is used to define which 
<em>message group</em> the message belongs to. The Message Group feature then 
ensures that all messages for the <em>same</em> message group will be sent to 
the <em>same</em> JMS consumer - whilst that consumer stays alive. As soon as 
 the consumer dies another will be chosen.</p><p>Another way of explaining 
Message Groups is that it provides sticky load balancing of messages across 
consumers; where the&#160;<strong><code>JMSXGroupID</code></strong> is kinda 
like a HTTP session ID or cookie value and the message broker is acting like a 
HTTP load balancer.</p><h3 id="MessageGroups-ExampleUseCase">Example Use 
Case</h3><p>Lets say we are doing some kind of order matching system where 
people are buying and selling things (stocks, shares, placing online bets, 
whatever). You want to have consumers who match bids and offers for different 
items (stocks / bets) so they want to keep in RAM for performance a sub-set of 
the data set. Therefore set the&#160;<strong><code>JMSXGroupID</code></strong> 
to be <strong><code>MSFT</code></strong>, 
<strong><code>IBM</code></strong>,&#160;<strong><code>SUNW</code></strong> and 
so forth to use the stock symbol to define the message group. (It can be any 
string whatsoever; maybe combining
  trading book, trading exchange, date and so forth - the more specific the 
group ID, the more concurrent you can run). Assume we are buying and selling 
<strong><code>MSFT</code>, <code>IBM</code>,&#160;<code>SUNW</code></strong> 
shares; the Message Groups feature guarantees that all 
the&#160;<strong><code>MSFT</code></strong> messages will be processed in order 
by the same consumer; ditto for&#160;<strong><code>IBM</code></strong> and 
<strong><code>SUNW</code></strong>.</p><h3 
id="MessageGroups-HowMessageGroupsWork">How Message Groups Work</h3><p>When a 
message is being dispatched to a consumer, 
the&#160;<strong><code>JMSXGroupID</code></strong> is checked. If one is 
present then the broker checks to see if a consumer owns that message group. 
Since there could be a large number of message groups hash buckets are used 
rather than the actual&#160;<strong><code>JMSXGroupID</code></strong> 
string.</p><p>If no consumer is associated with a message group a consumer is 
chosen. Said JMS&#16
 0;<strong><code>MessageConsumer</code></strong> will receive all further 
messages with the same&#160;<strong><code>JMSXGroupID</code></strong> value 
until:</p><ul><li>the consumer closes (or the client which created the consumer 
dies etc).</li><li>someone closes the message group by sending a message with a 
negative value for&#160;<strong><code>JMSXGroupSeq</code></strong> (see below 
for more details).</li></ul><p><strong>Note</strong>: as with message selector 
matching, grouping based on&#160;<strong><code>JMSXGroupID</code></strong> 
occurs before dispatch on messages in memory. With the 
default&#160;<strong><code>maxPageSize</code></strong> option, large backlogs 
of messages destined for one group can block receipt of messages to other 
groups if they don't all fit in memory. You can change the 
default&#160;<strong><code>maxPageSize</code></strong> setting for destinations 
as follows:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl
 ">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;destinationPolicy&gt;
+    &lt;policyMap&gt;
+       &lt;policyEntries&gt;
+           &lt;policyEntry queue="&gt;" maxPageSize="1000"/&gt;
+       &lt;/policyEntries&gt;
+    &lt;/policyMap&gt;
+&lt;/destinationPolicy&gt;</pre>
+</div></div><h3 id="MessageGroups-UsingMessageGroups">Using Message 
Groups</h3><p>You just need to change your JMS producers to fill in 
the&#160;<strong><code>JMSXGroupID</code></strong> message header with 
some&#160;<strong><code>String</code></strong> value of your 
choice.</p><p>Example:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">Mesasge message = 
session.createTextMessage("&lt;foo&gt;hey&lt;/foo&gt;");
 message.setStringProperty("JMSXGroupID", "IBM_NASDAQ_20/4/05");
 ...
 producer.send(message);
 </pre>
-</div></div>
-
-
-<h3 id="MessageGroups-ClosingaMessageGroup">Closing a Message Group</h3>
-
-<p>You generally don't need to close a message group; just keep using it. 
However if you really do want to close a group you can add a negative sequence 
number.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-Mesasge message = session.createTextMessage("&lt;foo&gt;hey&lt;/foo&gt;");
+</div></div><h3 id="MessageGroups-ClosingaMessageGroup">Closing a Message 
Group</h3><p>You generally don't need to close a message group; just keep using 
it. However if you really do want to close a group you can add a negative 
sequence number.</p><p>Example:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">Mesasge message = 
session.createTextMessage("&lt;foo&gt;hey&lt;/foo&gt;");
 message.setStringProperty("JMSXGroupID", "IBM_NASDAQ_20/4/05");
 message.setIntProperty("JMSXGroupSeq", -1);
 ...
 producer.send(message);
 </pre>
-</div></div>
-
-<p>This then <em>closes</em> the message group so if another message is sent 
in the future with the same message group ID it will be reassigned to a new 
consumer.</p>
-
-<h3 id="MessageGroups-Impliciations">Impliciations</h3>
-
-<p>Message Groups mean you get the power of <strong>grid</strong> processing 
of messages across a cluster of consumers with reliability, auto-failover, load 
balancing but you can also order the processing of messages too. So its the 
best of both worlds.</p>
-
-<p>However using the above example, what Message Groups actually do is to 
partition your work load across consumers using a user defineable partition 
strategy - the JMSXGroupID value.</p>
-
-<p>The neat thing about this is that you can do neat things like use lots of 
RAM caching; keep the order for MSFT in RAM in the MSFT consumer; keep the IBM 
orders in RAM in the IBM consumer - since the message broker is partitioning 
for you, you do not have to rely on a distributed cache with inter-cache 
synchronisation and locking to take advantage of caching.</p>
-
-<p>The great thing is - to the application developer, it looks like a simple 1 
consumer world where you process messages and do your job; leaving the broker 
to do all the hard stuff for you</p>
-
-<ul><li>partioning the traffic</li><li>load balancing of message groups across 
consumers</li><li>auto-failover of groups to different consumers as consumers 
come and go</li></ul>
-
-
-<p>In summary; if ordering or per-message caching and synchronization are in 
any way important to you then we highly recommend you use message groups to 
partition your traffic.</p>
-
-<h3 
id="MessageGroups-Gettingnotifiedofownershipchangesofmessagegroups">Getting 
notified of ownership changes of message groups</h3>
+</div></div><p>This then <em>closes</em> the message group so if another 
message is sent in the future with the same message group ID it will be 
reassigned to a new consumer.</p><h3 
id="MessageGroups-Implications">Implications</h3><p>Message Groups mean you get 
the power of <strong>grid</strong> processing of messages across a cluster of 
consumers with reliability, auto-failover, load balancing but you can also 
order the processing of messages too. So its the best of both worlds. However 
using the above example, what Message Groups actually do is to partition your 
work load across consumers using a user definable partition strategy - 
the&#160;<strong><code>JMSXGroupID</code></strong> value.</p><p>The neat thing 
about this is that you can do neat things like use lots of RAM caching; keep 
the order for&#160;<strong><code>MSFT</code></strong> in RAM in 
the&#160;<strong><code>MSFT</code></strong> consumer; keep 
the&#160;<strong><code>IBM</code></strong> orders in RAM in the&#160;<strong
 ><code>IBM</code></strong> consumer - since the message broker is partitioning 
 >for you, you do not have to rely on a distributed cache with inter-cache 
 >synchronization and locking to take advantage of caching.</p><p>The great 
 >thing is - to the application developer, it looks like a simple 1 consumer 
 >world where you process messages and do your job; leaving the broker to do 
 >all the hard stuff for you</p><ul><li>partitioning the traffic</li><li>load 
 >balancing of message groups across consumers</li><li>auto-failover of groups 
 >to different consumers as consumers come and go</li></ul><p>In summary; if 
 >ordering or per-message caching and synchronization are in any way important 
 >to you then we highly recommend you use message groups to partition your 
 >traffic.</p><h3 
 >id="MessageGroups-GettingNotifiedofOwnershipChangesofMessageGroups">Getting 
 >Notified of Ownership Changes of Message Groups</h3><p>ActiveMQ support a 
 >boolean header called&#160;<strong><code>JMSXGroupFirstForConsumer</code></st
 rong>. This header is set on the first message sent to a consumer for a 
particular message group.</p><p>If the JMS connection is 
using&#160;<strong><code>failover:</code></strong> and a temporary network 
error occurs so that the connection disconnects from the broker and reconnects 
some time later, a new consumer instance will be created under the covers of 
the JMS client leading to the possibility of another message with this header 
being set for the same message group.</p><p>Example:</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">String groupId = 
message.getStringProperty("JMSXGroupId");
 
-<p>In 4.1 onwards of ActiveMQ there is support for a new boolean header called 
<strong>JMSXGroupFirstForConsumer</strong> which will be set on the first 
message which is sent to a consumer for a particular message group.</p>
-
-<p>If the JMS connection is using <strong>failover:</strong> and a temporary 
network error occurs so that the connection disconnects from the broker and 
reconnects some time later, a new consumer instance will be created under the 
covers of the JMS client leading to the possibility of another message with 
this header being set for the same message group.</p>
-
-<p>So you can do code like...</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-String groupId = message.getStringProperty("JMSXGroupId");
 if (message.getBooleanProperty("JMSXGroupFirstForConsumer")) {
    // flush cache for groupId
 }
 </pre>
-</div></div>
-
-<p>To flush caches to ensure consistent state when faced with network 
errors.</p>
-
-<h3 id="MessageGroups-Addingnewconsumers">Adding new consumers</h3>
-
-<p>If you have existing messages in the broker and add consumers at a later 
stage, it is a good idea to delay message dispatch start until all consumers 
are present (or at least to give enough time for them to subscribe). If you 
don't do that the first consumer will probably acquire all message groups and 
all messages will be dispatched to it. You can achieve this by using 
<code>consumersBeforeDispatchStarts</code> and 
<code>timeBeforeDispatchStarts</code> <a shape="rect" 
href="per-destination-policies.html">destination policies</a>. </p>
-
-<p>Here's the example of the destination policy that delays dispatch for 
200ms</p>
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">                
-&lt;destinationPolicy&gt;
+</div></div><p>To flush caches to ensure consistent state when faced with 
network errors.</p><h3 id="MessageGroups-AddingNewConsumers">Adding New 
Consumers</h3><p>If you have existing messages in the broker and add consumers 
at a later stage, it is a good idea to delay message dispatch start until all 
consumers are present (or at least to give enough time for them to subscribe). 
If you don't do that the first consumer will probably acquire all message 
groups and all messages will be dispatched to it. You can achieve this by using 
<strong><code>consumersBeforeDispatchStarts</code></strong> and 
<strong><code>timeBeforeDispatchStarts</code></strong> <a shape="rect" 
href="per-destination-policies.html">destination policies</a>.</p><p>Here's the 
example of the destination policy that delays dispatch 
for&#160;<strong><code>200ms</code></strong>:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;destinationPolicy&gt;
   &lt;policyMap&gt;
     &lt;policyEntries&gt;
       &lt;policyEntry queue="&gt;" timeBeforeDispatchStarts="200"/&gt;
@@ -202,11 +119,8 @@ if (message.getBooleanProperty("JMSXGrou
   &lt;/policyMap&gt;
 &lt;/destinationPolicy&gt;
 </pre>
-</div></div>
-<p>The following code snippet shows how to wait for two consumers (or two 
seconds) before dispatch starts</p>
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">                
-&lt;destinationPolicy&gt;
+</div></div><p>The following code snippet shows how to wait for two consumers 
(or two seconds) before dispatch starts:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;destinationPolicy&gt;
   &lt;policyMap&gt;
     &lt;policyEntries&gt;
       &lt;policyEntry queue="&gt;" consumersBeforeDispatchStarts="2" 
timeBeforeDispatchStarts="2000"/&gt;
@@ -214,16 +128,7 @@ if (message.getBooleanProperty("JMSXGrou
   &lt;/policyMap&gt;
 &lt;/destinationPolicy&gt;
 </pre>
-</div></div>
-
-<p>As <a shape="rect" class="external-link" 
href="http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/usecases/MessageGroupDelayedTest.java?view=markup";>the
 appropriate test case</a> shows, adding a small time pause before dispatching 
or setting a minimum consumer number, ensures equal message group 
distribution.</p>
-
-<div class="confluence-information-macro confluence-information-macro-note"><p 
class="title">Availability</p><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
-<p>Available since version 5.3</p></div></div>
-
-<h3 id="MessageGroups-See">See</h3>
-
-<ul><li><a shape="rect" 
href="how-do-message-groups-compare-to-selectors.html">How do Message Groups 
compare to Selectors</a></li></ul></div>
+</div></div><p>As <a shape="rect" class="external-link" 
href="http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/usecases/MessageGroupDelayedTest.java?view=markup";>the
 appropriate test case</a> shows, adding a small time pause before dispatching 
or setting a minimum consumer number, ensures equal message group 
distribution.</p><div class="confluence-information-macro 
confluence-information-macro-note"><p class="title">Availability</p><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Available since version 
5.3</p></div></div><h3 id="MessageGroups-See">See</h3><ul><li><a shape="rect" 
href="how-do-message-groups-compare-to-selectors.html">How do Message Groups 
compare to Selectors</a></li></ul></div>
         </td>
         <td valign="top">
           <div class="navigation">

Modified: websites/production/activemq/content/slow-consumer-handling.html
==============================================================================
--- websites/production/activemq/content/slow-consumer-handling.html (original)
+++ websites/production/activemq/content/slow-consumer-handling.html Fri Sep 16 
23:22:09 2016
@@ -35,7 +35,6 @@
           <link 
href='http://activemq.apache.org/styles/highlighter/styles/shCore.css' 
rel='stylesheet' type='text/css' /> 
       <link 
href='http://activemq.apache.org/styles/highlighter/styles/shThemeEclipse.css' 
rel='stylesheet' type='text/css' /> 
       <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shCore.js' 
type='text/javascript'></script> 
-              <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script> 
               <script 
src='http://activemq.apache.org/styles/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script> 
          
       <script type="text/javascript"> 
@@ -82,70 +81,82 @@
   <tbody>
         <tr>
         <td valign="top" width="100%">
-<div class="wiki-content maincontent"><p><a shape="rect" 
href="slow-consumers.html">Slow Consumers</a> can cause problems on non-durable 
topics since they can force the broker to keep old messages in RAM which once 
it fills up, forces the broker to slow down producers, causing the fast 
consumers to be slowed down. One option we could implement in the future is 
spooling to disk - but then spooling to disk could slow down the fast consumers 
too.</p><p>Currently we have a strategy that lets you configure the maximum 
number of matched messages the broker will keep around for a consumer in 
addition to its prefetch buffer. Once this maximum is reached, as new messages 
come in, older messages are discarded. This allows you to keep the RAM for 
current messages and keep sending messages to a slow consumer but to discard 
old messages.</p><h2 
id="SlowConsumerHandling-PendingMessageLimitStrategy">Pending Message Limit 
Strategy</h2><p>You can configure the PendingMessageLimitStrategy implementat
 ion class on the destination map so that different regions of your topic 
namespace can have different strategies for dealing with slow consumers. For 
example you may want to use this strategy for prices which are very high volume 
but for orders and trades which are lower volume you might not wish to discard 
old messages.</p><p>The strategy calculates the maximum number of pending 
messages to be kept in RAM for a consumer (above its prefetch size). A value of 
zero means keep no messages around other than the prefetch amount. A value 
greater than zero will keep up to that amount of messages around, discarding 
the older messages as new messages come in. A value of -1 disables the 
discarding of messages.</p><p>We currently have 2 different implementations of 
the strategy.</p><h3 
id="SlowConsumerHandling-ConstantPendingMessageLimitStrategy">ConstantPendingMessageLimitStrategy</h3><p>This
 strategy uses a constant limit for all consumers (above their prefetch size). 
e.g.</p><div class="cod
 e panel pdl" style="border-width: 1px;"><div class="codeContent panelContent 
pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;constantPendingMessageLimitStrategy limit="50"/&gt;
+<div class="wiki-content maincontent"><p><a shape="rect" 
href="slow-consumers.html">Slow Consumers</a> can cause problems on non-durable 
topics since they can force the broker to keep old messages in RAM which once 
it fills up, forces the broker to slow down producers, causing the fast 
consumers to be slowed down. One option we could implement in the future is 
spooling to disk - but then spooling to disk could slow down the fast consumers 
too.</p><p>Currently we have a strategy that lets you configure the maximum 
number of matched messages the broker will keep around for a consumer in 
addition to its prefetch buffer. Once this maximum is reached, as new messages 
come in, older messages are discarded. This allows you to keep the RAM for 
current messages and keep sending messages to a slow consumer but to discard 
old messages.</p><h2 
id="SlowConsumerHandling-PendingMessageLimitStrategy">Pending Message Limit 
Strategy</h2><p>You can configure the&#160;<strong><code>PendingMessageLimitS
 trategy</code></strong> implementation class on the destination map so that 
different regions of your topic namespace can have different strategies for 
dealing with slow consumers. For example you may want to use this strategy for 
prices which are very high volume but for orders and trades which are lower 
volume you might not wish to discard old messages.</p><p>The strategy 
calculates the maximum number of pending messages to be kept in RAM for a 
consumer (above its prefetch size). A value of zero means keep no messages 
around other than the prefetch amount. A value greater than zero will keep up 
to that amount of messages around, discarding the older messages as new 
messages come in. A value of&#160;<strong><code>-1</code></strong> disables the 
discarding of messages.</p><p>There are currently two different implementations 
of the 
strategy:</p><ul><li><strong><code>ConstantPendingMessageLimitStrategy</code></strong></li><li><strong><code>PrefetchRatePendingMessageLimitStrategy</code
 ></strong></li></ul><h3 
 >id="SlowConsumerHandling-ConstantPendingMessageLimitStrategy">ConstantPendingMessageLimitStrategy</h3><p>This
 > strategy uses a constant limit for all consumers (above their prefetch 
 >size).</p><p>Example:</p><div class="code panel pdl" style="border-width: 
 >1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;constantPendingMessageLimitStrategy limit="50"/&gt;
 </pre>
 </div></div><h3 
id="SlowConsumerHandling-PrefetchRatePendingMessageLimitStrategy">PrefetchRatePendingMessageLimitStrategy</h3><p>This
 strategy calculates the maximum number of pending messages using a multiplier 
of the consumers prefetch size. So you could for example keep around 2.5 times 
the prefetch count for each consumer.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;prefetchRatePendingMessageLimitStrategy 
multiplier="2.5"/&gt;
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;prefetchRatePendingMessageLimitStrategy 
multiplier="2.5"/&gt;
 </pre>
-</div></div><h3 
id="SlowConsumerHandling-UsingthePrefetchPolicytoconfigurethelimit">Using the 
Prefetch Policy to configure the limit</h3><p>The JMS Client has a <a 
shape="rect" href="what-is-the-prefetch-limit-for.html">prefetch policy</a> you 
can use to configure the various prefetch limits for persistent &amp; non 
persistent queues &amp; topics. The prefetch policy also allows you to specify 
the maximumPendingMessageLimit on a per connection/consumer basis.</p><p>One 
minor difference with configuring this value; to simplify operation with 
non-JMS clients such as with <a shape="rect" href="openwire.html">OpenWire</a> 
the value of zero is ignored; so the lowest value you can configure is 
1.</p><h3 id="SlowConsumerHandling-ConfiguringtheEvictionPolicy">Configuring 
the Eviction Policy</h3><p>We have a MessageEvictionStrategy which is used to 
decide which message should be evicted on a slow consumer. The default 
implementation is</p><div class="code panel pdl" style="border-width: 1px;
 "><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;oldestMessageEvictionStrategy/&gt;
+</div></div><h3 
id="SlowConsumerHandling-UsingthePrefetchPolicytoConfiguretheLimit">Using the 
Prefetch Policy to Configure the Limit</h3><p>The JMS Client has a <a 
shape="rect" href="what-is-the-prefetch-limit-for.html">prefetch policy</a> you 
can use to configure the various prefetch limits for persistent and non 
persistent queues and topics. The prefetch policy also allows you to specify 
the&#160;<strong><code>maximumPendingMessageLimit</code></strong> on a per 
connection/consumer basis. One minor difference with configuring this value; to 
simplify operation with non-JMS clients such as with <a shape="rect" 
href="openwire.html">OpenWire</a> the value of zero is ignored; so the lowest 
value you can configure is <strong><code>1</code></strong>.</p><h3 
id="SlowConsumerHandling-ConfiguringtheEvictionPolicy">Configuring the Eviction 
Policy</h3><p>We have 
a&#160;<strong><code>MessageEvictionStrategy</code></strong> which is used to 
decide which message should be evicted on a slow consum
 er. The default implementation is:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;oldestMessageEvictionStrategy/&gt;
 </pre>
-</div></div><p>But you can write your own to use some application specific way 
of choosing. e.g. if you are sending market data price updates, you may wish to 
find an older price value, which might not be the oldest message. The 
implementation of this eviction strategy could be set (since version 5.6) 
using</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;uniquePropertyMessageEvictionStrategy 
propertyName="STOCK" /&gt;
+</div></div><p>However, you can write your own to use some application 
specific way of choosing messages for eviction. For example, if you are sending 
market data price updates you may wish to find an older price value, which 
might not be the oldest message.</p><p>Example:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;uniquePropertyMessageEvictionStrategy 
propertyName="STOCK"/&gt;
 </pre>
-</div></div><p>where <code>propertyName</code> is the JMS message property 
that specifies the price.</p><p>Another option could be to use the oldest 
message with the lowest priority message - so if you have some high priority 
messages, evict the lower priority messages first even if they are 
newer.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;oldestMessageWithLowestPriorityEvictionStrategy/&gt;
+</div></div><p>where <strong><code>propertyName</code></strong> is the JMS 
message property that specifies the price.</p><p>Another option could be to use 
the oldest message with the lowest priority message. Therefore if you have some 
high priority messages, evict the lower priority messages first even if they 
are newer.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;oldestMessageWithLowestPriorityEvictionStrategy/&gt;
 </pre>
-</div></div><h2 id="SlowConsumerHandling-Example">Example</h2><p>The following 
example shows an ActiveMQ broker configuration file. Notice that for topics in 
the <strong>PRICES.&gt;</strong> wildcard range the 
<strong>pendingMessageLimitStrategy</strong> property is set to only keep 
around 10 messages for each consumer above their prefetch buffer size.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;beans 
-  xmlns="http://www.springframework.org/schema/beans"; 
-  xmlns:amq="http://activemq.apache.org/schema/core";
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-  xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
-  http://activemq.apache.org/schema/core 
http://activemq.apache.org/schema/core/activemq-core.xsd"&gt;
+</div></div><h2 id="SlowConsumerHandling-Example">Example</h2><p>The following 
example shows an ActiveMQ broker configuration file. Notice that for topics in 
the <strong><code>PRICES.&gt;</code></strong> wildcard range 
the&#160;<strong><code>pendingMessageLimitStrategy</code></strong> property is 
set to only keep around&#160;<strong><code>10</code></strong> messages for each 
consumer above their prefetch buffer size.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;beans 
xmlns="http://www.springframework.org/schema/beans"; 
+       xmlns:amq="http://activemq.apache.org/schema/core";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                           
http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://activemq.apache.org/schema/core
+                          
&#160;http://activemq.apache.org/schema/core/activemq-core.xsd"&gt;
+                           
   &lt;bean 
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/&gt;
-  &lt;broker persistent="false" brokerName="${brokername}" 
xmlns="http://activemq.apache.org/schema/core"&gt;
+  
+  &lt;broker xmlns="http://activemq.apache.org/schema/core"; 
+          persistent="false" 
+          brokerName="${brokername}"&gt;
+          
     &lt;!--  lets define the dispatch policy --&gt;
     &lt;destinationPolicy&gt;
       &lt;policyMap&gt;
         &lt;policyEntries&gt;
+
           &lt;policyEntry topic="FOO.&gt;"&gt;
             &lt;dispatchPolicy&gt;
-              &lt;roundRobinDispatchPolicy /&gt;
+              &lt;roundRobinDispatchPolicy/&gt;
             &lt;/dispatchPolicy&gt;
             &lt;subscriptionRecoveryPolicy&gt;
-              &lt;lastImageSubscriptionRecoveryPolicy /&gt;
+              &lt;lastImageSubscriptionRecoveryPolicy/&gt;
             &lt;/subscriptionRecoveryPolicy&gt;
           &lt;/policyEntry&gt;
+          
           &lt;policyEntry topic="ORDERS.&gt;"&gt;
             &lt;dispatchPolicy&gt;
-              &lt;strictOrderDispatchPolicy /&gt;
+              &lt;strictOrderDispatchPolicy/&gt;
             &lt;/dispatchPolicy&gt;
+
             &lt;!--  1 minutes worth --&gt;
             &lt;subscriptionRecoveryPolicy&gt;
-              &lt;timedSubscriptionRecoveryPolicy recoverDuration="60000" /&gt;
+              &lt;timedSubscriptionRecoveryPolicy recoverDuration="60000"/&gt;
             &lt;/subscriptionRecoveryPolicy&gt;
           &lt;/policyEntry&gt;
+          
           &lt;policyEntry topic="PRICES.&gt;"&gt;
             &lt;!-- lets force old messages to be discarded for slow consumers 
--&gt;
             &lt;pendingMessageLimitStrategy&gt;
               &lt;constantPendingMessageLimitStrategy limit="10"/&gt;
             &lt;/pendingMessageLimitStrategy&gt;
+
             &lt;!--  10 seconds worth --&gt;
             &lt;subscriptionRecoveryPolicy&gt;
-              &lt;timedSubscriptionRecoveryPolicy recoverDuration="10000" /&gt;
+              &lt;timedSubscriptionRecoveryPolicy recoverDuration="10000"/&gt;
             &lt;/subscriptionRecoveryPolicy&gt;
-            
           &lt;/policyEntry&gt;
-          &lt;policyEntry tempTopic="true" advisoryForConsumed="true" /&gt;
-          &lt;policyEntry tempQueue="true" advisoryForConsumed="true" /&gt;
+          
+          &lt;policyEntry tempTopic="true" advisoryForConsumed="true"/&gt;
+          &lt;policyEntry tempQueue="true" advisoryForConsumed="true"/&gt;
+          
         &lt;/policyEntries&gt;
       &lt;/policyMap&gt;
     &lt;/destinationPolicy&gt;
   &lt;/broker&gt;
 &lt;/beans&gt;</pre>
-</div></div><h2 id="SlowConsumerHandling-Usagetips">Usage tips</h2><p>It is 
advisable that if you know a particular consumer is going to be slow then set 
its prefetch size to something smaller than the fast consumers. e.g. if you 
know a particular box is quite slow and you have very high message rates and 
you have some very fast consumers; you might want to enable this feature and 
set the prefetch on the slow boxes to a little lower than on the fast 
boxes.</p><h3 
id="SlowConsumerHandling-Monitoringthestatusofslowconsumers">Monitoring the 
status of slow consumers</h3><p>You can also use a <a shape="rect" 
href="jmx.html">JMX</a> Console to view the statistics of the active 
subscriptions. This allows you to view the following statistics on a 
TopicSubscriptionViewMBean</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Statistic</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Meaning</p></th></tr><tr><td c
 olspan="1" rowspan="1" class="confluenceTd"><p>discarded</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>The count of how many messages 
have been discarded during the lifetime of the subscription due to it being a 
slow consumer</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>matched</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>The current number of messages matched and to be 
dispatched to the subscription as soon as some capacity is available in the 
prefetch buffer. So a non-zero value implies that the prefetch buffer is full 
for this subscription</p></td></tr></tbody></table></div></div>
+</div></div><h2 id="SlowConsumerHandling-UsageTips">Usage 
Tips</h2><p>&#160;</p><div class="confluence-information-macro 
confluence-information-macro-tip"><span class="aui-icon aui-icon-small 
aui-iconfont-approve confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>It is advisable that if you know a 
particular consumer is going to be slow then set its prefetch size to something 
smaller than the fast consumers!</p><p>For example, if you know a particular 
server is quite slow and you have very high message rates<em> and</em> you have 
some very fast consumers then you might want to enable this feature and set the 
prefetch on the slow servers to be a <em>little</em> lower than on the fast 
servers.</p></div></div><h3 
id="SlowConsumerHandling-MonitoringtheStatusofSlowConsumers">Monitoring the 
Status of Slow Consumers</h3><p>You can also use a <a shape="rect" 
href="jmx.html">JMX</a> Console to view the statistics of the active 
subscriptions. This allo
 ws you to view the following statistics on a 
<strong><code>TopicSubscriptionViewMBean</code></strong>:</p><div 
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Statistic</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Definition</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p><code>discarded</code></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>The count of how many messages 
have been discarded during the lifetime of the subscription due to it being a 
slow consumer</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><code>matched</code></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>The current number of messages matched and 
to be dispatched to the subscription as soon as some capacity is available in 
the prefetch buffer. So a non-zero value implies that the prefetch buffer is 
full for this subscription</p></td></tr></tbody></table></div></div>
         </td>
         <td valign="top">
           <div class="navigation">



Reply via email to