Virtual destinations are faster than Camel routing

Routing messages from one input queue to two output queues in ActiveMQ can be done in two different ways. Apache Camel, a powerful rule-based routing engine often used with ActiveMQ, is a typical choice. Virtual composite queue is another solution. Which to choose? The faster.

Apache Camel

Camel configuration I use:

<beans
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="activemq:INPUT-QUEUE"/>
            <to uri="activemq:OUTPUT-1-QUEUE"/>
            <to uri="activemq:OUTPUT-2-QUEUE"/>
        </route>
    </camelContext>

    <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" >
        <property name="connectionFactory">
          <bean class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="vm://localhost?create=false&amp;waitForStart=10000" />
            <property name="userName" value="${activemq.username}"/>
            <property name="password" value="${activemq.password}"/>
          </bean>
        </property>
    </bean>
</beans>

Benchmark took 3 minutes 31 seconds to send 10 thousand messages through Camel:

$ time ./amqinject INPUT-QUEUE 10000
0.651u 0.490s 3:31.43 0.5%      0+0k 0+0io 0pf+0w

Unfortunately “Number Of Pending Messages” was always about 1024 and amqinject gets blocked in send() call:

INFO | Usage Manager memory limit reached on queue://INPUT-QUEUE. Producers will be throttled to the rate at which messages are removed from this destination to prevent flooding it. See http://activemq.apache.org/producer-flow-control.html for more info

Virtual Composite Queue

Virtual destinations are configured in <broker> tag. Here is my configuration:

        <destinations>
            <queue physicalName="INPUT-QUEUE" />
            <queue physicalName="OUTPUT-1-QUEUE" />
            <queue physicalName="OUTPUT-2-QUEUE" />
        </destinations>

        <destinationInterceptors>
        <virtualDestinationInterceptor>
            <virtualDestinations>
            <compositeQueue name="INPUT-QUEUE">
            <forwardTo>
                <queue physicalName="OUTPUT-1-QUEUE" />
                <queue physicalName="OUTPUT-2-QUEUE" />
            </forwardTo>
            </compositeQueue>
            </virtualDestinations>
        </virtualDestinationInterceptor>
        </destinationInterceptors>

Amqinject never blocked and it took only 2 minutes 29 seconds to complete:

% time ./amqinject INPUT-QUEUE 10000
0.718u 0.539s 2:29.33 0.8%      0+0k 0+0io 0pf+0w

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.