blob: c35fcfdff802620acec9642b8c712b1f47cf5808 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ActiveMQ</title>
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/css/main.css">
<script defer src="/js/fontawesome-all.min.js" integrity="sha384-rOA1PnstxnOBLzCLMcre8ybwbTmemjzdNlILg8O7z1lUkLXozs4DHonlDtnE7fpc"></script>
<script src="/js/jquery.slim.min.js" integrity="sha384-5AkRS45j4ukf+JbWAfHL8P4onPA9p0KwwP7pUdjSQA3ss9edbJUJc/XcYAiheSSz"></script>
<script src="/js/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"></script>
<script src="/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light fixed-top">
<div class="container">
<!-- <a class="navbar-brand mr-auto" href="#"><img style="height: 50px" src="assets/img/apache-feather.png" /></a> -->
<a class="navbar-brand mr-auto" href="/"><img src="/assets/img/activemq_logo_black_small.png" style="height: 50px"/></a>
<button class="navbar-toggler ml-auto" type="button" data-toggle="collapse" data-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="ml-auto collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="/news">News</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link" id="navbarDropdownComponents" data-target="#" href="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Components<span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-center" aria-labelledby="navbarDropdownComponents">
<div class="row">
<div class="col-12">
<ul class="multi-column-dropdown">
<li class="nav-item"><a class="dropdown-item" href="/components/classic">ActiveMQ Classic</a></li>
<li class="nav-item"><a class="dropdown-item" href="/components/artemis/">ActiveMQ Artemis</a></li>
<li class="nav-item"><a class="dropdown-item" href="/components/nms">NMS Clients</a></li>
<li class="nav-item"><a class="dropdown-item" href="/components/cms">CMS Client</a></li>
</ul>
</div>
</div>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link" id="navbarDropdownCommunity" data-target="#" href="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Community<span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-center multi-column columns-1" aria-labelledby="navbarDropdownCommunity">
<div class="row">
<div class="col-12">
<ul class="multi-column-dropdown">
<li class="nav-item"><a class="dropdown-item" href="/contact">Contact Us</a></li>
<li class="nav-item"><a class="dropdown-item" href="/contributing">Contribute</a></li>
<li class="nav-item"><a class="dropdown-item" href="/issues">Report Issues</a></li>
<li class="nav-item"><a class="dropdown-item" href="/support">Get Support</a></li>
</ul>
</div>
</div>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link" id="navbarDropdownTeam" data-target="#" href="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><img src="/assets/img/feather.png" style="height:20px">Apache<span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-center multi-column columns-1" aria-labelledby="navbarDropdownTeam">
<div class="row">
<div class="col-sm-12">
<ul class="multi-column-dropdown">
<li class="nav-item"><a class="dropdown-item" href="https://www.apache.org">The Apache Software Foundation</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://www.apache.org/licenses/">License</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
<li class="nav-item"><a class="dropdown-item" href="/security-advisories">Security</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://www.apache.org/events/current-event">Events</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://people.apache.org/phonebook.html?pmc=activemq">PMC & Committers</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://whimsy.apache.org/board/minutes/ActiveMQ.html">Board Reports</a></li>
<li class="nav-item"><a class="dropdown-item" href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy Policy</a></li>
</ul>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="content">
<div class="page-title-classic">
<div class="container">
<h1>Message Cursors</h1>
</div>
</div>
<div class="container" >
<div class="row" style="margin-top: 30px">
<div class="col-12 classic">
<p><a href="features">Features</a> &gt; <a href="message-dispatching-features">Message Dispatching Features</a> &gt; <a href="message-cursors">Message Cursors</a></p>
<h2 id="message-cursors">Message Cursors</h2>
<p>A common problem in previous versions of ActiveMQ Classic was <a href="my-producer-blocks">running out of RAM buffer</a> when using non-persistent messaging.</p>
<p>Beginning with ActiveMQ Classic 5.0.0, there is a new memory model that allows messages to be paged in from storage when space is available (using Store cursors for persistent messages).</p>
<p>Releases prior to 5.0 kept references in memory for all the messages that could be dispatched to an active Durable Topic Consumer or a Queue. While a reference itself is not large, it does impose a limit on the maximum number of messages that can be pending delivery.</p>
<p>A typical approach for messaging systems dispatching persistent messages is to pull them in batches from long term storage when a client is ready to consume them, using a cursor to maintain the next to dispatch position. This is a robust and very scalable approach, but not the most performant for cases when the consumer(s) can keep up with the producer(s) of messages.</p>
<p>ActiveMQ Classic 5.0 takes a hybrid approach, allowing messages to pass from producer to consumer directly (after the messages have been persisted), but switches back to using cursors if the consumer(s) fall behind.</p>
<p>When Message Consumers are both active and fast - keeping up with the Message Producer</p>
<p><img src="assets/img/DispatchFastConsumers.png" alt="" /></p>
<p>If a Consumer becomes active after messages are pending from the store for it, or it’s slower than the producer, then messages are paged in to the dispatch queue from a pending cursor:</p>
<p><img src="assets/img/DispatchSlowConsumers.png" alt="" /></p>
<h3 id="types-of-cursor">Types of Cursor</h3>
<p>The default message cursor type in ActiveMQ Classic 5.0 is Store based.  It behaves as above. There are two additional types of cursor that could be used: <strong>VM Cursor</strong> and <strong>File based Cursor</strong>, described below.</p>
<h4 id="vm-cursor">VM Cursor</h4>
<p>The VM Cursor is how ActiveMQ Classic 4.x works: references to a message are held in memory, and passed to the dispatch queue when needed. This can be very fast, but also has the downside of not being able to handle very slow consumers or consumers that have been inactive for a long time: <img src="/images/VMCursor.png" alt="" /></p>
<h4 id="file-based-cursor">File based Cursor</h4>
<p>The File based Cursor is dervied from the VM Cursor.  When memory in the broker reaches its limit, it can page messages to temporary files on disk. This type of cursor can be used when the message store might be relatively slow, but consumers are generally fast. By buffering to disk, it allows the message broker to handle message bursts from producers without resorting to paging in from slow storage:</p>
<p><img src="assets/img/FileCursor.png" alt="" /></p>
<h4 id="paging-for-non-persistent-messages">Paging for Non-Persistent Messages</h4>
<p>The store based cursor also handles cursors for non-persistent messages, which are not stored in the message store. Non-persistent messages are passed directly to the cursor, so the store based cursor embeds a file based cursor just for these types of messages:</p>
<p><img src="assets/img/NonPersistentMsgs.png" alt="" /></p>
<h3 id="configuring-cursors">Configuring Cursors</h3>
<p>By default, Store based cursors are used, but it is possible to configure different cursors depending on the destination.</p>
<h4 id="topic-subscribers">Topic subscribers</h4>
<p>For Topics there is a dispatch queue and pending cursor for every subscriber.  It’s possible to configure different policies for durable subscribers and transient subscribers - e.g:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;destinationPolicy&gt;
&lt;policyMap&gt;
&lt;policyEntries&gt;
&lt;policyEntry topic="org.apache.&gt;" producerFlowControl="false" memoryLimit="1mb"&gt;
&lt;dispatchPolicy&gt;
&lt;strictOrderDispatchPolicy /&gt;
&lt;/dispatchPolicy&gt;
&lt;deadLetterStrategy&gt;
&lt;individualDeadLetterStrategy topicPrefix="Test.DLQ." /&gt;
&lt;/deadLetterStrategy&gt;
&lt;pendingSubscriberPolicy&gt;
&lt;vmCursor /&gt;
&lt;/pendingSubscriberPolicy&gt;
&lt;pendingDurableSubscriberPolicy&gt;
&lt;vmDurableCursor/&gt;
&lt;/pendingDurableSubscriberPolicy&gt;
&lt;/policyEntry&gt;
&lt;/policyEntries&gt;
&lt;/policyMap&gt;
&lt;/destinationPolicy&gt;
</code></pre></div></div>
<p>Valid Subscriber types are <strong><em>vmCursor</em></strong> and <strong><em>fileCursor.</em></strong> The default is the store based cursor.</p>
<p>Valid Durable Subscriber cursor types are <strong><em>storeDurableSubscriberCursor</em></strong>, <strong><em>vmDurableCursor</em></strong> and <strong><em>fileDurableSubscriberCursor.</em></strong> The default is the store based cursor</p>
<h4 id="queues">Queues</h4>
<p>For Queues there is a single dispatch Queue and pending Queue for every destination, so configuration is slightly different:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;destinationPolicy&gt;
&lt;policyMap&gt;
&lt;policyEntries&gt;
&lt;policyEntry queue="org.apache.&gt;"&gt;
&lt;deadLetterStrategy&gt;
&lt;individualDeadLetterStrategy queuePrefix="Test.DLQ."/&gt;
&lt;/deadLetterStrategy&gt;
&lt;pendingQueuePolicy&gt;
&lt;vmQueueCursor /&gt;
&lt;/pendingQueuePolicy&gt;
&lt;/policyEntry&gt;
&lt;/policyEntries&gt;
&lt;/policyMap&gt;
&lt;/destinationPolicy&gt;
</code></pre></div></div>
<p>Valid Queue cursor types are <strong><em>storeCursor</em></strong>, <strong><em>vmQueueCursor</em></strong> and <strong><em>fileQueueCursor.</em></strong> The default is the store based cursor</p>
<h3 id="see-also">See Also</h3>
<ul>
<li><a href="producer-flow-control">Producer Flow Control</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row sitemap">
<div class="col-sm-12">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-3">
<div >
<img class="float-left" style="max-height: 100px" src="/assets/img/activemq_logo_white_vertical_small.png"/>
</div>
</div>
<div style="text-align: center; margin-bottom: 0px; margin-top: 30px; font-size: 65%" class="col-sm-6">
<p><a href="https://www.apache.org/foundation/marks/list/">Apache, ActiveMQ, Apache ActiveMQ</a>, the Apache feather logo, and the Apache ActiveMQ project logo are trademarks of The Apache Software Foundation. Copyright &copy; 2024, The Apache Software Foundation. Licensed under <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
</div>
<div class="col-sm-3">
<div >
<a href="https://www.apache.org"><img class="float-right" style="margin-top: 10px; max-height: 80px" src="/assets/img/apache-logo-small.png"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>