Reputation: 479
My question is very similar to this one: Why is there a delay in Spring AMQP Message dispatching from a filled Queue?
I can see a delay between two invocations of my message listener even when the queue is filled with messages. I have put a log message with the time at the very begining of the method, the time at the end, and the time that took the method (in milliseconds):
Start - End - Time
2016-09-21T10:08:55.263; - 2016-09-21T10:08:55.278; - 15;
2016-09-21T10:08:55.356; - 2016-09-21T10:08:55.356; - 0;
2016-09-21T10:08:55.388; - 2016-09-21T10:08:55.388; - 0;
2016-09-21T10:08:55.466; - 2016-09-21T10:08:55.466; - 0;
The time processing the message is about 10 ms (in average) but I can see delays greater tan 50 ms (sometimes greater tan 100 ms).
If I change the parameter PrefetchCount of the SimpleMessageListenerContainer (for example to 200), then the performance increase considerabily, and now I can see in the logs that the delay has desapear:
Start - End - Time
2016-09-21T10:26:27.336; - 2016-09-21T10:26:27.336; - 0;
2016-09-21T10:26:27.336; - 2016-09-21T10:26:27.351; - 15;
2016-09-21T10:26:27.351; - 2016-09-21T10:26:27.351; - 0;
2016-09-21T10:26:27.351; - 2016-09-21T10:26:27.351; - 0;
My questions are:
My configuration is like this:
@Bean
public MessageListenerAdapter broadcastMessageListenerAdapter() {
return new MessageListenerAdapter(myHandlerBroadcast(), "onMessage");
}
@Bean(name="myBroadcastMessageListenerContainer")
public SimpleMessageListenerContainer myBroadcastMessageListenerContainer()
{
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(myConnectionFactory());
container.setQueueNames(PX_BROADCAST_QUEUE + environment.getProperty("my.user"));
container.setMessageListener(broadcastMessageListenerAdapter());
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
container.setMessageConverter(myMessageConverter());
container.setConcurrentConsumers(1);
container.setAutoStartup(false);
container.setPrefetchCount(500); // ¿1?
return container;
}
@Bean(name="myHandlerBroadcast")
public MyHandlerBroadcast myHandlerBroadcast(){
return new MyHandlerBroadcast();
}
Upvotes: 1
Views: 177
Reputation: 174554
Yes; it's network. You can "prove" it by using a network monitor. By default prefetchCount
is 1 which means the broker only allows one un-acked message at the consumer. Only when that message is ack'd is the next one sent.
Increasing the prefetch count dramatically increases performance but can cause out-of-order delivery.
What that really mean?
Consider a prefetch count of 10. You process 5 messages and then have a failure (#6) and the message is rejected and requeued (if so configured).
Message #6 will be redelivered when you have consumed all your prefetched messages - hence it will be out of order.
If you never requeue messages then there is no problem with message delivery order.
Upvotes: 3