1. Business Scenario:
Same as the <Active MQ in Action> section 5.6's example: Real-time data delivery of pricing information for a trading platform.
2. Solution:
Non-persistent message and Caching messages in the broker for consumers.
We can implement the above solution easily by just lines of configuration, but my critical question is: how to measure the performance improvement and the reliability loss?
3. Performance Test
Refer to R3
4. Reliability Test
We consider Active MQ's proprietary advisory messages. Most interesting topics for me are as shown in the picture below.
5. Change Implementation
5.1 Non-persistent Configuration
Active MQ side: persistent="false"
<?xml version="1.0" encoding="UTF-8"?> <beans> <broker brokerName="test-broker" persistent="false" xmlns="http://activemq.apache.org/schema/core"> <transportConnectors> <transportConnector uri="tcp://localhost:61635"/> </transportConnectors> </broker> </beans>
JMS client side (Spring JMS Template Configuration): deliveryMode=non-persistent
<property name="deliveryMode"> <value>1</value> </property>
5.2 (Deprecated)Configuring the subscription recovery policy
<broker brokerName="broker" persistent="true" useShutdownHook="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.apache.org/schema/core"> <transportConnectors> <transportConnector uri="tcp://localhost:61635"/> </transportConnectors> <destinationPolicy> <policyMap> <policyEntries> <policyEntry topic="Topic.FixedSizedSubs.>"> <subscriptionRecoveryPolicy> <fixedSizeSubscriptionRecoveryPolicy maximumSize="2000000" useSharedBuffer="false"/> </subscriptionRecoveryPolicy> </policyEntry> <policyEntry topic="Topic.NoSubs.>"> <subscriptionRecoveryPolicy> <noSubscriptionRecoveryPolicy/> </subscriptionRecoveryPolicy> </policyEntry> <policyEntry topic="Topic.TimedSubs.>"> <subscriptionRecoveryPolicy> <timedSubscriptionRecoveryPolicy recoverDuration="25000"/> </subscriptionRecoveryPolicy> </policyEntry> </policyEntries> </policyMap> </destinationPolicy> </broker>
5.3 Ensure Consumer Not Slow
5.3.1 Set alwaysSessionAsync=false
This allows messages to be passed directly from the transport to the message consumer. Please refer to <Active in Action>'s section 13.3.3 for detailed reason.
<bean id= "tsTopicConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" alwaysSessionAsync="false" p:brokerURL="${ts.desttopic.connfac}" />
5.3.2 SingleConnectionFactory VS CachingConnectionFactory
Connection Factory choice. Please read reference 4 first. I can't see any reason not to use CachingConnectionFactory.
5.4 Advisory Message Configuration for Testing
6. Go Further Optimization
Embedded broker, avoid message copying.
Reference:
[1] Active MQ in Action.
[2] http://activemq.apache.org/advisory-message.html
[3] http://activemq.apache.org/jmeter-performance-tests.html
[4] http://java.dzone.com/articles/spring-and-caching-jms