Usually when dealing with an EIP such as Splitter, Multicast, or Aggregator, the default pool of 10 threads that is created for the EIP is sufficient. However, each of these patterns allow you to provide a customized pool if this default pool is inadequate for your needs.
This recipe will outline how to define a custom thread pool in Camel.
The Java code for this recipe is located in the org.camelcookbook.parallelprocessing.threadpools
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with threadPools
.
To define a custom thread pool using the XML DSL, add a threadPool
definition before any routes in the camelContext
element:
<camelContext xmlns="http://camel.apache.org/schema/spring">
<threadPool id="customThreadPool"
poolSize="5"
thread Name="CustomThreadPool"/>
<route>
<!-- ... -->
</route>
</camelContext>
The id
attribute of the threadPool
can be used within the executorServiceRef
attribute of any EIP that supports parallel processing. The following XML DSL fragment inserts our customThreadPool
into a threads
block as described in the Spreading the load within a route using a set of threads recipe:
<threads executorServiceRef="customThreadPool">
The Java DSL can also use thread pools defined in this manner:
.threads().executorServiceRef("customThreadPool")
When a threadPool
is defined in the XML DSL, an ExecutorService
object is instantiated with the attributes specified, and registered in the Camel Registry with the given id
.
This is most commonly seen where Java RouteBuilder
implementations are used in conjunction with the XML DSL, as in a Spring or OSGi Blueprint application. In these cases, the routeBuilder
references should be defined before the threadPool
:
<bean id="routeBuilderUsingRef" class="org.camelcookbook.parallelprocessing.threadpools.CustomThreadPoolRefRouteBuilder"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <routeBuilder ref="routeBuilderUsingRef"/> <threadPool id="customThreadPool" poolSize="5" maxQueueSize="100" thread Name="CustomThreadPool"/> </camelContext>
We can see the custom pool being used through the log output:
Processing Message[3]:Camel (camel-1) thread #12 - CustomThreadPool
If you are not using the XML DSL, it is possible to define an instance of the java.util.concurrent.ExecutorService
interface alongside your route using an org.apache.camel.builder.ThreadPoolBuilder
class.
ExecutorService executorService = new ThreadPoolBuilder(context).poolSize(5) .maxQueueSize(100).build("CustomThreadPool");
The value passed to the build()
method is the pattern that will be assigned to thread names.
The builder takes the Camel context as an argument, and registers itself as a pool whose lifecycle can be managed by the context.
You can then refer to the pool instance through the executorService()
DSL statement in any EIP that supports parallel processing:
.threads().executorService(customExecutorService)
You can customize a number of settings when defining pools, including:
Setting |
Description |
---|---|
|
The core thread pool size used (mandatory). |
|
The maximum number of threads that the pool should contain. |
|
How long inactive threads should be kept alive for. |
|
A |
|
The maximum number of exchanges to hold in the queue for servicing; a value of -1 indicates an unbounded queue. |
|
How to handle messages that arrive in the queue when its |
The last two options govern the behavior of the in-memory queue that feeds the thread pool.
You also have to define a custom thread name for the threads in the pool via the threadNamePattern
attribute. The name may contain a limited set of placeholders:
threadNamePattern="#camelId#:CustomThreadPool[#counter#]"
The following placeholders can be used as a part of the pattern:
Placeholder |
Description |
---|---|
|
The name of the Camel context |
|
An incrementing counter |
|
The original thread name |
|
An automatically generated long name that includes some additional information from Camel |
18.217.107.229