简体   繁体   中英

Replay Messages sent over ActiveMQ

Is there an easy way to create a copy of every message sent over a queue, so that if needed, the user could browse the list of previously transmitted messages and replay them numerous times with the click of a button?

I have program X that sends a message to a queue and program Y then reads it in. I would like to be able to replay a message that was previously sent without having to go back to program X and regenerate it again.

There are easy ways to get started, if you have not too many messages or too many queues.

First, you could setup copying of messages to a "copy queue". This has to be done once per queue with this strategy. Like this in activemq.xml

    <destinationInterceptors>
      <virtualDestinationInterceptor>
        <virtualDestinations>
          <compositeQueue name="INVOICE.OUT">
            <forwardTo>
              <queue physicalName="INVOICE.IN" />
              <queue physicalName="INVOICE.COPY" />
            </forwardTo>
          </compositeQueue>
        </virtualDestinations>
      </virtualDestinationInterceptor>
    </destinationInterceptors>

Then use a tool to browse through the messages on the COPY queue, and if needed, resend them to the OUT queue. I like the Hermes JMS tool for such things.

If you want something more fancy, you could read up on mirrored queues .

There is another rather simple way to achieve easy copy of all messages.

Use apache-camel that is bundled with activemq. This config inside camel.xml would achieve automatic copy of all messages to queues that begins with FOO.* This route would need some fixup of the copy queue name, but in priniple it works as a one time config for wiretapping.

<route>
   <from uri="activemq:FOO.>"/>
   <setHeader headerName="CamelJMSDestination">
     <simple>COPY.${header.JMSDestination}</simple>
   </setHeader>
   <to uri="activemq:dummy"/>
</route>

A very important aspect here is that your server will fill up over time if you store all messages. I suggest you read up on ActiveMQ memory management or, just keep message copies for given timeframe. This can be automated in the sense that the sending system can actually set a message expiry so that messages get deleted automatically after a number of days/weeks/months.

There is no easy way, I am afraid, since such a behavior would sort of violate the idea of a queuing system. However, there are some things you can try:

  1. This is a bit hacky: send the messages to a Durable Queue (and make sure the messages are durable themselves) and disable auto-acknowledge. If you do not acknowledge any message, the server will keep them and you can use a QueueBrowser to access them. However, they will eventually time-out
  2. Store a copy of each message when it reaches program Y. Actually, you just need to store a reference to make sure the messages is not garbage-collected. Depending on your message rate and available memory, you will have to purge messages eventually
  3. Create an ActiveMQ Plugin. This is definitely the most elaborate and most complex of the three. You'll create a plugin (see ActiveMQ's documentation on how to create those) and intercept message in the plugin's send() or preDispatch() methods. There you store a copy of it's content . You will also have to listen for replay requests and send your history upon request (you can make use of the reply-to field in JMS Message headers). The statistics plugin that comes with ActiveMQ is a good source to start here. Oh and of course your server will also run out of memory eventually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM