I have a dsl flow which works great with Queue channel. However, when i make it synchronous using Rendezvous channel, i get acknowledgement rate at most 30 messages/second. My handlers are take just 350 microseconds to finish the process but the acknowledgement rate keeps low. This piles up rabbit queue drastically. I even scaled concurrent consumers to 10 and increased prefetch too but this did not help. Then i added couple of more scaled instances itself but that helped raise ack rate to around 45/sec.
How can I make flow acknowledge faster? I am expecting rate of over 500 per second.
Dsl Flow:
SimpleMessageListenerContainer simpleMessageListenerContainer = profileTagRabbitMLCConfig.transactedChannelSpanRabbitSMLC(queueName)
simpleMessageListenerContainer?.setConcurrentConsumers(concurrentConsumer)
simpleMessageListenerContainer?.setPrefetchCount(prefetch)
return IntegrationFlows.from(Amqp.inboundAdapter(simpleMessageListenerContainer))
.channel(rendezvousTransformerChannel1())
.transform(myTransformer, 'transform', { e -> e.advice(adviceWithRecoverer) })
.channel(rendezvousTransformerChannel2())
.handle(myHandler, 'save', { e -> e.advice(adviceWithRecoverer) })
.get()
Synchronous Channels:
@Bean
MessageChannel rendezvousTransformerChannel1() {
return MessageChannels.rendezvous().get()
}
@Bean
MessageChannel rendezvousHandlerChannel() {
return MessageChannels.rendezvous().get()
}
Container:
SimpleMessageListenerContainer
transactedChannelSpanRabbitSMLC(CachingConnectionFactory rabbitConnectionFactory, String queueName){
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer()
container.setConnectionFactory(rabbitConnectionFactory)
container.setQueueNames(queueName)
container.setChannelTransacted(true)
container
}
Recovery advice for retry:
Advice getRetryAdviceWithRecovery() {
RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice()
advice.setRetryTemplate(getRetryTemplate())
advice.recoveryCallback = getRecoveryCallback() // sends message to rabbit exchange
advice
}
Poller:
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedDelay(100).maxMessagesPerPoll(500L).get();
}