Friday, September 13, 2013

ActiveMQ Configuration for persistent Message Delivery


Document  Version 1.0

Copyright © 2012-2013 beijing.beijing.012@gmail.com


Wether message is delivered persistent or not, depends on both message producer. i.e. the client, and configuration of server, in our case ActiveMQ. 

1. On the Client Side 


Message Producer can tell ActiveMQ to deliver message in persistent mode in 2 ways:

- with MessageProducer#setDeliveryMode(..), this set the default delivery mode for all messges sent with this producer.
- MessageProducer# send(..), this set delivery mode on message level, i.e.  set delivery mode for each message.


2. On the Server Side 


If persistence delivery is not enabled on ActiveMQ, messages will not be delivered in persistence mode even if message producer  set  delivery mode as "PERSISTENT"

2.1 Set persistent mode

With ActiveMQ, persistent node is set on broker tag of activemq.xml

The default:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

When no persistent properties is set  for broker, the default is  persistent="true". i.e.


<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" persistent="true" >


2.2 Configure persistence Adapter


When broker is configured to run in persistence mode, it requires a "persistenceAdapter", for example:


     <persistenceAdapter>
            <kahaDB directory="${activemq.base}/data/kahadb"/>
        </persistenceAdapter>

The above is also the default configuration, if no persistence apdapter is configured in activemq.xml

2.3 Pesistence Store Usage

Having configured persistence adapter as "khdb", as next step we need to tell how much disk size is available for "khdb" to store messages:

   <systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage limit="64 mb"/>
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/> <!-- default was 50 gb -->
                </tempUsage>
            </systemUsage>
        </systemUsage>

When no "systemUsage" section is configured, the ActiveMQ use default 100gb for "khdb" storeUsage.
When there is no enough space available on the disk, ActiveMQ will show ERROR/WARN message at startup like:

2013-09-13 09:05:15,136 | WARN  | Store limit is 102400 mb, whilst the data directory: /activemq/data/localhost/KahaDB only has 20603 mb of usable space | org.apache.activemq.broker.BrokerService | main

ActiveMQ can be started and live with such error/warnings, But if you are running a production system, be sure to check if you really need more disk.

2.4 Running in "NON_PERSISTENT" mode


When broker is configured with "persistent=false", then ActiveMQ persists no messges at all in DB even if client set delivery mode as "persistent".

Running in "persistent=false" mode, ActiveMQ use default MemoryPersistenceAdapter. All messages resides in ActiveMQ' system memory. When the limit of the system usage is reached, message will be stored in "tempStore" on file system. 



<systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage limit="10 gb"/>
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/> <!-- default was 50 gb -->
                </tempUsage>
            </systemUsage>
        </systemUsage>


Here the "memoryUsage" of system memory, is RAM, and is not the whole memory used by ActiveMQ, but only the memory used for storing messages. When the total available RAM on the machine is less than what is configured above, ActiveMQ can still start and works, but logs error info like:


2013-09-13 09:49:19,078 | ERROR | Memory Usage for the Broker (10240 mb) is more than the maximum available for the JVM: 981 mb | org.apache.activemq.broker.BrokerService | main


My test machine has only 8gb RAM, but here above configuration requires 10gb for ActiveMQ's in memory store.


Beside the above error, at sartup, my ActiveMQ show also following error info:


  2013-09-13 09:49:19,078 | ERROR | Temporary Store limit is 51200 mb, whilst the temporary data directory: /activemq/data/localhost/tmp_storage only has 20570 mb of usable space | 


This is because, ActiveMQ is configured to use 50GB temp space on disk, howeve my machine has only about 20gb free.


The configuration for "storeUsage" here is not used by ActiveMQ, sicnce in non-persistent mode, no data is writen is written to DB.