JBoss ActiveMQ Topic RedeliveryDelay too small

Question!

I use JBoss with the default ActiveMQ to send messages to some clients which have subscribed to a topic. Unfortunately onMessage(Message message) gets called multiple times for just one message.

JNDI-Lookup:

private static void lookupRemoteTopic() throws NamingException, JMSException
{
    final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
    final String DEFAULT_DESTINATION = "jms/topic/refresh";
    final String DEFAULT_USERNAME = "ejb";
    final String DEFAULT_PASSWORD = "ejbSuperSecret";
    final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
    final String PROVIDER_URL = "http-remoting://192.168.2.72:8080";

    final Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
    env.put(Context.PROVIDER_URL, PROVIDER_URL);
    env.put(Context.SECURITY_PRINCIPAL, DEFAULT_USERNAME);
    env.put(Context.SECURITY_CREDENTIALS, DEFAULT_PASSWORD);
    InitialContext namingContext = new InitialContext(env);

    // Perform the JNDI lookups
    TopicConnectionFactory connectionFactory = (TopicConnectionFactory) namingContext.lookup(DEFAULT_CONNECTION_FACTORY);
    Topic destination = (Topic) namingContext.lookup(DEFAULT_DESTINATION);

    TopicConnection con = connectionFactory.createTopicConnection(DEFAULT_USERNAME, DEFAULT_PASSWORD);        
    con.start();
    TopicSession session = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    TopicSubscriber sub = session.createSubscriber(destination);
    sub.setMessageListener(this);
}

onMessage:

public void onMessage(Message message)
{
    try
    {
        // Do some stuff with it
    }
    catch (JMSException e)
    {
        e.printStackTrace();
    }
}

Message sender:

@Inject
private JMSContext context;
@Resource(lookup = "java:/jms/topic/refresh")
private Destination topic;

MapMessage mesg = context.createMapMessage();
// set message body
context.createProducer().send(topic, mesg);

After one message has been send, the clients get bombarded with messages, although AUTO_ACKNOWLEDGE is set.

How can I slow the sender down?

If an SSCCE is needed, I can provide one, it is just a lot to include (server, client, configuration, etc)



Answers

The broker is doing it's job which is to deliver messages to your client as fast as it can. If your client can't handle that then there are other tools like Apache Camel which provide Throttler type components which you can use to insert in between the client and broker to slow down the incoming messages. ActiveMQ supports embedded Camel routes so you could set this up on the broker.

If you want maximum control of the rate that messages are processed in your application then you should switch to the synchronous consumer model and call receive on your consumer only when you are ready to process a new message.

By : Tim Bish


You can check for yourself:

Measure-Command {
    1..100000 | ForEach-Object $_
}

1.17s

Measure-Command {
    foreach ($i in (1..100000))
    {
    $i
    }
}

0.15s
By : Avshalom


Yes, there is a performance difference. foreach is faster than ForEach-Object, but requires more memory, because all items ($folders) must be in memory. ForEach-Object processes one item at a time as they're passed through the pipeline, so it has a smaller memory footprint, but isn't as fast as foreach.

See also.



This video can help you solving your question :)
By: admin