blob: 886ebe6a44e29ff907aad35c4b1f7d7d8bd488f7 [file]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.23">
<link rel="icon" type="image/png" href="images/favicon.png">
<title>Thread management</title>
<link rel="stylesheet" href="css/asciidoctor.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/rouge-github.css">
<script>
document.addEventListener("DOMContentLoaded", function() {
const pathSegments = window.location.pathname.split('/');
if (window.location.hostname == "artemis.apache.org" && pathSegments[pathSegments.length - 2] != "latest") {
var message = document.createElement("div");
message.style.margin = "20px";
message.style.textAlign = "center";
message.style.backgroundColor = "#FFFFE0";
message.textContent = "Please be aware that this documentation is out of date. ";
var link = document.createElement("a");
link.href = "../../latest";
link.textContent = "Here is the latest documentation.";
message.appendChild(link);
document.body.insertBefore(message, document.body.firstChild);
}
});
</script>
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Thread management</h1>
<div id="toc" class="toc2">
<div id="toctitle"><a href="index.html">User Manual for 2.55.0</a></div>
<ul class="sectlevel1">
<li><a href="#server-side-thread-management">1. Server-Side Thread Management</a>
<ul class="sectlevel2">
<li><a href="#scheduled-thread-pool">1.1. Scheduled Thread Pool</a></li>
<li><a href="#general-purpose-thread-pool">1.2. General Purpose Thread Pool</a></li>
<li><a href="#asynchronous-io">1.3. Asynchronous IO</a></li>
<li><a href="#paging">1.4. Paging</a></li>
<li><a href="#netty-acceptors">1.5. Netty Acceptors</a></li>
<li><a href="#other-server-side-threads">1.6. Other Server-Side Threads</a></li>
</ul>
</li>
<li><a href="#client-side-thread-management">2. Client-Side Thread Management</a>
<ul class="sectlevel2">
<li><a href="#scheduled-thread-pool-2">2.1. Scheduled Thread Pool</a></li>
<li><a href="#general-purpose-thread-pool-2">2.2. General Purpose Thread Pool</a></li>
<li><a href="#netty-connectors">2.3. Netty Connectors</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This chapter describes how Apache Artemis uses and pools threads and how you can manage them.</p>
</div>
<div class="paragraph">
<p>First we&#8217;ll discuss how threads are managed and used on the server side then we&#8217;ll look at the client side.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="server-side-thread-management"><a class="anchor" href="#server-side-thread-management"></a><a class="link" href="#server-side-thread-management">1. Server-Side Thread Management</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Thread pools exist for each of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>scheduled tasks</p>
</li>
<li>
<p>general use</p>
</li>
<li>
<p>asynchronous IO</p>
</li>
<li>
<p>paging</p>
</li>
<li>
<p>remoting (managed by Netty on a per-acceptor basis)</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">Broker Identification in Thread Names</div>
<div class="paragraph">
<p>Many thread names contain broker identification.
This is done to assist in cases where multiple brokers are running in the same JVM (e.g. in the test-suite).
The identification which appears in the thread name is determined by the following in order of precedence:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>identity</code> set in the internal <code>ConfigurationImpl</code> object (done by tests)</p>
</li>
<li>
<p><code>name</code> set in <code>broker.xml</code></p>
</li>
<li>
<p>the hexadecimal representation of the <code>ActiveMQServerImpl</code> Java Object&#8217;s identity acquired via <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#identityHashCode(java.lang.Object)"><code>System.identityHashCode</code></a></p>
</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="scheduled-thread-pool"><a class="anchor" href="#scheduled-thread-pool"></a><a class="link" href="#scheduled-thread-pool">1.1. Scheduled Thread Pool</a></h3>
<div class="paragraph">
<p>The scheduled thread pool is used for most activities on the server side that require running periodically or with delays.
This includes tasks like scanning:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>queues for expired messages or scheduled deliveries</p>
</li>
<li>
<p>configuration files for changes</p>
</li>
<li>
<p>unused addresses &amp; queues for deletion</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The maximum number of thread used by this pool is configure in <code>broker.xml</code> with the <code>scheduled-thread-pool-max-size</code> parameter, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="xml"><span class="nt">&lt;scheduled-thread-pool-max-size&gt;</span>10<span class="nt">&lt;/scheduled-thread-pool-max-size&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The default <code>scheduled-thread-pool-max-size</code> is <code>5</code> . A value of <code>0</code> is not allowed.</p>
</div>
<div class="paragraph">
<p>The name for threads from this pool will contain <code>activemq-scheduled</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="general-purpose-thread-pool"><a class="anchor" href="#general-purpose-thread-pool"></a><a class="link" href="#general-purpose-thread-pool">1.2. General Purpose Thread Pool</a></h3>
<div class="paragraph">
<p>This general purpose thread pool is used for most asynchronous actions on the server side.
The maximum number of threads used by this pool is configure in <code>broker.xml</code> with the <code>thread-pool-max-size</code> parameter, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="xml"><span class="nt">&lt;thread-pool-max-size&gt;</span>60<span class="nt">&lt;/thread-pool-max-size&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The default <code>thread-pool-max-size</code> is <code>30</code>.
A value of <code>-1</code> signifies that the thread pool has <em>no upper bound</em> and new threads will be created on demand if there are not enough threads already available to satisfy demand.
A value of <code>0</code> is not allowed.</p>
</div>
<div class="paragraph">
<p>Any threads in this pool which are idle for <code>60</code> seconds will be terminated.</p>
</div>
<div class="paragraph">
<p>The name for threads from this pool will contain <code>activemq-&lt;brokerName&gt;</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="asynchronous-io"><a class="anchor" href="#asynchronous-io"></a><a class="link" href="#asynchronous-io">1.3. Asynchronous IO</a></h3>
<div class="paragraph">
<p>Threads from this pool are used for journal-related disk I/O, JDBC, &amp; replication.</p>
</div>
<div class="paragraph">
<p>The name for threads from this pool will contain <code>activemq-io-&lt;brokerName&gt;</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="paging"><a class="anchor" href="#paging"></a><a class="link" href="#paging">1.4. Paging</a></h3>
<div class="paragraph">
<p>Threads from this pool are used to write to and read from paging (disk or JDBC).</p>
</div>
<div class="paragraph">
<p>The name for threads from this pool will contain <code>activemq-paging-&lt;brokerName&gt;</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="netty-acceptors"><a class="anchor" href="#netty-acceptors"></a><a class="link" href="#netty-acceptors">1.5. Netty Acceptors</a></h3>
<div class="paragraph">
<p>Netty threads for processing network traffic, by default, are capped on a per-acceptor basis at three times the number of cores (or hyper-threads) as reported by <code>Runtime.getRuntime().availableProcessors()</code>.
To override this value, you can set the number of threads by specifying the parameter <code>remotingThreads</code> in the transport configuration.
See the <a href="configuring-transports.html#configuring-the-transport">configuring transports</a> for more information on this.</p>
</div>
<div class="paragraph">
<p>Threads names will include the name of their corresponding acceptor with the prefix <code>activemq-remoting-</code>.
For example, for the acceptor named <code>amqp</code> the corresponding thread names will contain <code>activemq-remoting-amqp-&lt;brokerName&gt;</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="other-server-side-threads"><a class="anchor" href="#other-server-side-threads"></a><a class="link" href="#other-server-side-threads">1.6. Other Server-Side Threads</a></h3>
<div class="paragraph">
<p>A thread dump from the server&#8217;s JVM will have other threads as well.
Here are other names you might find in a thread dump and the function they perform.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>activemq-web</code></dt>
<dd>
<p>thread pool managed by Jetty (i.e. the <a href="web-server.html">embedded web server</a>) to handle HTTP connections (e.g. from the web console or other Jolokia clients)</p>
</dd>
<dt class="hdlist1"><code>activemq-failure-check-thread</code></dt>
<dd>
<p>checks TTL on incoming connections</p>
</dd>
<dt class="hdlist1"><code>activemq-buffer-timeout</code></dt>
<dd>
<p>flushes disk IO buffers upon timeout</p>
</dd>
<dt class="hdlist1"><code>activemq-libaio-poller</code></dt>
<dd>
<p>polls AIO for callbacks</p>
</dd>
<dt class="hdlist1"><code>activemq-critical-analyzer</code></dt>
<dd>
<p>monitors for timeouts of various critical server operations</p>
</dd>
<dt class="hdlist1"><code>activemq-shutdown-timer</code></dt>
<dd>
<p>monitors configuration directory for status file to stop the server</p>
</dd>
<dt class="hdlist1"><code>activemq-remoting-service</code></dt>
<dd>
<p>in-vm connectivity and invoking failure listeners for Netty</p>
</dd>
<dt class="hdlist1"><code>Log4j2-TF-*-Scheduled-*</code></dt>
<dd>
<p>executes Log4j2 tasks related to <code>CronTriggeringPolicy</code> used by default <code>log4j2.properties</code></p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="client-side-thread-management"><a class="anchor" href="#client-side-thread-management"></a><a class="link" href="#client-side-thread-management">2. Client-Side Thread Management</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>On the Core client thread pools exist for each of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>scheduled tasks</p>
</li>
<li>
<p>general use</p>
</li>
<li>
<p>flow control</p>
</li>
<li>
<p>remoting (managed by Netty on a per-connector basis)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These are used by all clients using the same classloader in a JVM.</p>
</div>
<div class="paragraph">
<p>If required each <code>ClientSessionFactory</code> instance can be configured so that it does not use these global static pools but instead maintains individual pools.
Any sessions created from that <code>ClientSessionFactory</code> will use those pools instead.
This is configured using the <code>useGlobalPools</code> boolean URL parameter.
The default is <code>true</code>.</p>
</div>
<div class="sect2">
<h3 id="scheduled-thread-pool-2"><a class="anchor" href="#scheduled-thread-pool-2"></a><a class="link" href="#scheduled-thread-pool-2">2.1. Scheduled Thread Pool</a></h3>
<div class="paragraph">
<p>The scheduled thread pool is used for activities that require running periodically or with delays.
This includes tasks like:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>sending <code>PING</code> packets to the broker</p>
</li>
<li>
<p>flushing network data to the wire if <code>batchDelay</code> &gt; <code>0</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The maximum number of threads used by this pool can be configured using the <code>scheduledThreadPoolMaxSize</code> URI parameter, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="nowrap">tcp://host:61616?scheduledThreadPoolMaxSize=10</pre>
</div>
</div>
<div class="paragraph">
<p>The Java system property <code>activemq.artemis.client.global.scheduled.thread.pool.core.size</code> can also be used.</p>
</div>
<div class="paragraph">
<p>The default <code>scheduledThreadPoolMaxSize</code> is <code>5</code>.
A value of <code>0</code> is not allowed.</p>
</div>
<div class="paragraph">
<p>If using a global pool the name for threads will contain <code>activemq-client-global-scheduled</code>.
If using a non-global pool the name for threads will contain <code>activemq-client-factory-scheduled</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="general-purpose-thread-pool-2"><a class="anchor" href="#general-purpose-thread-pool-2"></a><a class="link" href="#general-purpose-thread-pool-2">2.2. General Purpose Thread Pool</a></h3>
<div class="paragraph">
<p>This general purpose thread pool is used for most asynchronous actions.
The maximum number of threads used by this pool is configured using the <code>threadPoolMaxSize</code> URI parameter, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="nowrap">tcp://host:61616?threadPoolMaxSize=10</pre>
</div>
</div>
<div class="paragraph">
<p>By default, a global pool will be used and the default <code>threadPoolMaxSize</code> will be <code>Runtime.getRuntime().availableProcessors()</code> * 8.
If using a non-global pool the default <code>threadPoolMaxSize</code> is <code>-1</code>.
A value of <code>-1</code> signifies that the thread pool has <em>no upper bound</em> and new threads will be created on demand if there are not enough threads already available to satisfy demand.
A value of <code>0</code> is not allowed.
The minimum valid value is <code>2</code>.</p>
</div>
<div class="paragraph">
<p>Any threads in this pool which are idle for <code>60</code> seconds will be terminated.</p>
</div>
<div class="paragraph">
<p>The name for threads from this pool will contain <code>activemq-client-factory</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="netty-connectors"><a class="anchor" href="#netty-connectors"></a><a class="link" href="#netty-connectors">2.3. Netty Connectors</a></h3>
<div class="paragraph">
<p>Netty threads for processing network traffic, by default, are capped on a per-connector basis at three times the number of cores (or hyper-threads) as reported by <code>Runtime.getRuntime().availableProcessors()</code>.
To override this value, you can set the number of threads by specifying the URI parameter <code>remotingThreads</code>.
See the <a href="configuring-transports.html#configuring-the-transport">configuring transports</a> for more information on this.</p>
</div>
<div class="paragraph">
<p>Threads names will include the name of their corresponding acceptor with the prefix <code>activemq-remoting-</code>.
For example, for the acceptor named <code>amqp</code> the corresponding thread names will contain <code>activemq-remoting-amqp-&lt;brokerName&gt;</code>.</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>