Exchange Pooling

Apache Camel requires a tiny resource overhead when routing message.

For example the routing engine keeps state of each individual message, keeping track of the message flow, and where messaging are going next. The routing engine also handles complex tasks such as error handling, capturing metrics, and many other things. All together small numbers of Java objects is allocated on the heap for each processing step during routing.

With the advance of cloud computing, where work loads are precisely measured, then Camel has undergone a series of core optimizations to reduce its overhead.

Pooling objects to reduce object allocations

The Exchange Pooling functionality is object pooling by recycling commonly used objects by the routing enginge.

The most significant object being reused is the org.apache.camel.Exchange object that is the root object that holds the message with its payload, headers, meta-data and other content.

Besides pooling exchanges then internal objects used by the routing engine is also pooled and recycled. All together this dramatically reduces the object allocations, from camel core itself.

There will always be objects allocations from the actual message content (payload and headers), and also from the Camel components in use and its 3rd party libraries. The footprint of Camel core and its routing engine is close to zero, when pooling is enabled.

This all sounds marvelous so what is the negatives? Yes the price to pay for object pooling, is the complexity of managing the pool (acquire and returning objects to the pool); however all of this is taken care of by Camel itself. The object pools are using JDK ConcurrentMap instances and take up very little memory. The negative is very tiny CPU cost on adding and removing objects from the pools, and resetting the objects before reuse.

It is possible better to sacrifice the very tiny CPU cost for reduced object allocations, which helps to avoid the JVM garbage collection running more frequently, and causing your application to halt or delay processing messages at any given time.

Enabling Exchange Pooling

The object pooling is currently not enabled by default, and requires to be turned on.

This can be done as shown in Java:

CamelContext context = ...
context.adapt(ExtendedCamelContext.class).setExchangeFactory(new PooledExchangeFactory());

If using Camel Main, Camel Spring Boot, or Camel Quarkus you can enable this in the application.properties:

camel.main.exchange-factory = pooled

Configuration Options

The exchange pool can be configured with the following options:

Option Description Default

exchange-factory

Whether to use pooling or not. Possible values are prototype or pooled

prototype

exchange-factory-capacity

Maximum number of elemenets in the pool

100

exchange-factory-statistics-enabled

Whether to capture usage statistics

false

Management

If object pooling is enabled, then Camel provides a JMX MBean which allows to introspect the pools and its usage via JMX. This requires to add camel-management JAR to the classpath.

Examples

We have provided a few examples which we are using for performance profiling. For example the basic timer-log example.