2014-12-11 07:17:29 -05:00
|
|
|
# Thread management
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2015-04-27 17:32:30 -04:00
|
|
|
This chapter describes how Apache ActiveMQ Artemis uses and pools threads and how you
|
2014-12-04 10:25:29 -05:00
|
|
|
can manage them.
|
|
|
|
|
|
|
|
First we'll discuss how threads are managed and used on the server side,
|
|
|
|
then we'll look at the client side.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## Server-Side Thread Management
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2015-04-27 17:32:30 -04:00
|
|
|
Each Apache ActiveMQ Artemis Server maintains a single thread pool for general use, and
|
2014-12-04 10:25:29 -05:00
|
|
|
a scheduled thread pool for scheduled use. A Java scheduled thread pool
|
|
|
|
cannot be configured to use a standard thread pool, otherwise we could
|
|
|
|
use a single thread pool for both scheduled and non scheduled activity.
|
|
|
|
|
2016-10-27 11:30:10 -04:00
|
|
|
Apache ActiveMQ Artemis will, by default, cap its thread pool
|
2014-12-04 10:25:29 -05:00
|
|
|
at three times the number of cores (or hyper-threads) as reported by `
|
|
|
|
Runtime.getRuntime().availableProcessors()` for processing
|
|
|
|
incoming packets. To override this value, you can set the number of
|
2015-02-25 08:37:19 -05:00
|
|
|
threads by specifying the parameter `nioRemotingThreads` in the
|
|
|
|
transport configuration. See the [configuring transports](configuring-transports.md)
|
|
|
|
for more information on this.
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
There are also a small number of other places where threads are used
|
|
|
|
directly, we'll discuss each in turn.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Server Scheduled Thread Pool
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
The server scheduled thread pool is used for most activities on the
|
|
|
|
server side that require running periodically or with delays. It maps
|
|
|
|
internally to a `java.util.concurrent.ScheduledThreadPoolExecutor`
|
|
|
|
instance.
|
|
|
|
|
|
|
|
The maximum number of thread used by this pool is configure in
|
2015-04-29 05:30:31 -04:00
|
|
|
`broker.xml` with the `scheduled-thread-pool-max-size`
|
2014-12-04 10:25:29 -05:00
|
|
|
parameter. The default value is `5` threads. A small number of threads
|
|
|
|
is usually sufficient for this pool.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### General Purpose Server Thread Pool
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
This general purpose thread pool is used for most asynchronous actions
|
|
|
|
on the server side. It maps internally to a
|
|
|
|
`java.util.concurrent.ThreadPoolExecutor` instance.
|
|
|
|
|
|
|
|
The maximum number of thread used by this pool is configure in
|
2015-04-29 05:30:31 -04:00
|
|
|
`broker.xml` with the `thread-pool-max-size` parameter.
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
If a value of `-1` is used this signifies that the thread pool has no
|
|
|
|
upper bound and new threads will be created on demand if there are not
|
|
|
|
enough threads available to satisfy a request. If activity later
|
|
|
|
subsides then threads are timed-out and closed.
|
|
|
|
|
|
|
|
If a value of `n` where `n`is a positive integer greater than zero is
|
|
|
|
used this signifies that the thread pool is bounded. If more requests
|
|
|
|
come in and there are no free threads in the pool and the pool is full
|
|
|
|
then requests will block until a thread becomes available. It is
|
|
|
|
recommended that a bounded thread pool is used with caution since it can
|
|
|
|
lead to dead-lock situations if the upper bound is chosen to be too low.
|
|
|
|
|
|
|
|
The default value for `thread-pool-max-size` is `30`.
|
|
|
|
|
|
|
|
See the [J2SE
|
|
|
|
javadoc](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.htm)
|
|
|
|
for more information on unbounded (cached), and bounded (fixed) thread
|
|
|
|
pools.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Expiry Reaper Thread
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
A single thread is also used on the server side to scan for expired
|
|
|
|
messages in queues. We cannot use either of the thread pools for this
|
|
|
|
since this thread needs to run at its own configurable priority.
|
|
|
|
|
2015-03-24 07:50:58 -04:00
|
|
|
For more information on configuring the reaper, please see [message expiry](message-expiry.md).
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Asynchronous IO
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
Asynchronous IO has a thread pool for receiving and dispatching events
|
|
|
|
out of the native layer. You will find it on a thread dump with the
|
2015-04-27 17:32:30 -04:00
|
|
|
prefix ActiveMQ-AIO-poller-pool. Apache ActiveMQ Artemis uses one thread per opened
|
2014-12-04 10:25:29 -05:00
|
|
|
file on the journal (there is usually one).
|
|
|
|
|
|
|
|
There is also a single thread used to invoke writes on libaio. We do
|
|
|
|
that to avoid context switching on libaio that would cause performance
|
|
|
|
issues. You will find this thread on a thread dump with the prefix
|
|
|
|
ActiveMQ-AIO-writer-pool.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## Client-Side Thread Management
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2015-04-27 17:32:30 -04:00
|
|
|
On the client side, Apache ActiveMQ Artemis maintains a single static scheduled thread
|
2014-12-04 10:25:29 -05:00
|
|
|
pool and a single static general thread pool for use by all clients
|
|
|
|
using the same classloader in that JVM instance.
|
|
|
|
|
|
|
|
The static scheduled thread pool has a maximum size of `5` threads, and
|
|
|
|
the general purpose thread pool has an unbounded maximum size.
|
|
|
|
|
2015-04-27 17:32:30 -04:00
|
|
|
If required Apache ActiveMQ Artemis can also be configured so that each
|
2014-12-04 10:25:29 -05:00
|
|
|
`ClientSessionFactory` instance does not use these static pools but
|
|
|
|
instead maintains its own scheduled and general purpose pool. Any
|
|
|
|
sessions created from that `ClientSessionFactory` will use those pools
|
|
|
|
instead.
|
|
|
|
|
|
|
|
To configure a `ClientSessionFactory` instance to use its own pools,
|
|
|
|
simply use the appropriate setter methods immediately after creation,
|
|
|
|
for example:
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
``` java
|
|
|
|
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(...)
|
|
|
|
|
|
|
|
ClientSessionFactory myFactory = locator.createClientSessionFactory();
|
|
|
|
|
|
|
|
myFactory.setUseGlobalPools(false);
|
|
|
|
|
|
|
|
myFactory.setScheduledThreadPoolMaxSize(10);
|
|
|
|
|
2015-02-25 08:37:19 -05:00
|
|
|
myFactory.setThreadPoolMaxSize(-1);
|
2014-12-11 07:17:29 -05:00
|
|
|
```
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
If you're using the JMS API, you can set the same parameters on the
|
|
|
|
ClientSessionFactory and use it to create the `ConnectionFactory`
|
|
|
|
instance, for example:
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
``` java
|
|
|
|
ConnectionFactory myConnectionFactory = ActiveMQJMSClient.createConnectionFactory(myFactory);
|
|
|
|
```
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
If you're using JNDI to instantiate `ActiveMQConnectionFactory`
|
|
|
|
instances, you can also set these parameters in the JNDI context
|
|
|
|
environment, e.g. `jndi.properties`. Here's a simple example using the
|
|
|
|
"ConnectionFactory" connection factory which is available in the context
|
|
|
|
by default:
|
|
|
|
|
2015-04-30 05:44:16 -04:00
|
|
|
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
|
2015-02-25 08:37:19 -05:00
|
|
|
|
2015-02-24 10:50:54 -05:00
|
|
|
java.naming.provider.url=tcp://localhost:61616
|
2015-02-25 08:37:19 -05:00
|
|
|
|
2014-12-04 10:25:29 -05:00
|
|
|
connection.ConnectionFactory.useGlobalPools=false
|
2015-02-25 08:37:19 -05:00
|
|
|
|
2014-12-04 10:25:29 -05:00
|
|
|
connection.ConnectionFactory.scheduledThreadPoolMaxSize=10
|
2015-02-25 08:37:19 -05:00
|
|
|
|
2014-12-04 10:25:29 -05:00
|
|
|
connection.ConnectionFactory.threadPoolMaxSize=-1
|
2014-12-11 07:17:29 -05:00
|
|
|
|