Using custom thread pools

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.

Getting ready

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.

How to do it...

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")

How it works...

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.

Tip

The same thread pool can be re-used by a number of different routes, or EIP elements, although care should be taken so as not to starve any individual routes of worker threads.

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)

There's more...

You can customize a number of settings when defining pools, including:

Setting

Description

poolSize

The core thread pool size used (mandatory).

maxPoolSize

The maximum number of threads that the pool should contain.

keepAliveTime

How long inactive threads should be kept alive for.

timeUnit

A java.util.concurrent.TimeUnit interface used in conjunction with keepAliveTime (for example, MILLISECONDS, SECONDS, MINUTES).

maxQueueSize

The maximum number of exchanges to hold in the queue for servicing; a value of -1 indicates an unbounded queue.

rejectedPolicy

How to handle messages that arrive in the queue when its maxQueueSize has been reached. Can be either Abort (throw an exception), CallerRuns, Discard, or DiscardOldest.

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

camelId

The name of the Camel context

counter

An incrementing counter

name

The original thread name

longName

An automatically generated long name that includes some additional information from Camel

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.9.169