Where does spring rabbit consume a message on a new thread - spring

I'm working on tracing rabbitmq, and I've found that spring rabbit consumes a message on a new thread. I wanna know where does it create a new thread

See Choosing a Container.
The (default) SimpleMessageListenerContainer passes the messages to a dedicated thread for each consumer; the thread(s) are created when the container is start()ed. You can specify a custom TaskExecutor. By default, it uses a SimpleAsyncTaskExecutor.
The DirectMessageListenerContainer calls the listener on the amqp-client dispatcher thread.

Related

How and where to use JmsListenerEndpointRegistry start and stop function using SpringBoot?

I want to stop/pause the queue so that (https://issues.apache.org/jira/browse/AMQ-5229)
NO messages sent to the associate consumers
messages still to be enqueued on the queue
ability to be able to browse the queue
all the JMX counters for the queue to be available and correct.
Added: Apache ActiveMQ (Version 5.16.2)
But I don't know where to create the bean of JmsListenerEndpointRegistry and call start and stop method.
Sample code will be appreciated. Thanks.
The JmsListenerEndpointRegistry is automatically configured by Spring Boot.
Simply #Autowired it into the controlling class, give the JmsListener an id and stop/start it using the id.
Note: this does not use the AMQ feature you referenced; it simply tells the listener container to stop/start receiving messages.

Integration with external systems over JMS. Clustered environment

I have an application where I created 2 message listener containers for external system A which listens two queues respectively.
Also I have 1 message listener container which running and listening another queue of external system B. I am using spring DefaultMessageListenerContainer.
My application is running on clustered environment, while defining my message listener container I injected to it my listener which implements javax MessageListener interface and acts as kind of MDB.
So my questions are:
Is it normal to have instance of message listener container per queue?
Will my message driven pojo (MDP) execute onMessage() on each application node?
If yes, how can I avoid it? I want each message to be consumed once on some of the application nodes.
What is default behavior of DefaultMessageListenerContainer, message is acknowledged as soon as I reached onMessage or after I finished execution of onMessage? Or maybe I need to acknowledge it manually?
See the spring framework JMS documentation and the JMS specification.
Yes it is normal - a container can only listen to one destination.
It depends on the destination type; for a topic, each instance will get a copy of the message; for a queue, multiple listeners (consumers) will compete for messages. This has nothing to do with Spring, it's the way JMS works.
See #2.
With the DMLC, it is acknowledged immediately before calling the container; set sessionTransacted = true so the ack is not committed until the listener exits. With a SimpleMessageListenerContainer, the message is ack'd when the listener exits. See the Javadocs for the DMLC and SMLC (as well as the abstract classes they subclass) for the differences.

Spring Integration: Message Driven Channel Adapter

As per the documentation int-jms:message-driven-channel-adapter uses SimpleAsyncTaskExecutor
SimpleAsyncTaskExecutor doesn't reuse threads and creates a new thread for each task. In case of message-driven-channel-adapter what is the definition of a task?
In case of message driven channel Adapter the task is a constantly polling loop. So, this is going to be a long- living resource which keeps thread active. Therefore we don’t care too much about source of threads. See Spring JMS for more information.

RabbitMQ Channel reuse (SimpleMessageContainer)

My spring boot application's is functionality it to listen to the messages on rabbitmq queue, do some processing in onMessage, and then publish the message on another rabbitmq queue. We are using spring-rabbit (1.7.2.RELEASE). We have configured listener using SimpleMessageListenerContainer.
My question is can i publish using he same channel on which I am reading he messages. Does spring-rabbit provides access to channel used by listener? so that same channel can be reused to publish?
Thanks,
Smita
If you use transactions (listener container), any operations performed by a transactional RabbitTemplate on the container thread will participate in the transaction and use the same channel.
If you are not using transactions, you can use a ChannelAwareMessageListener to access the channel the message was received on. See Message Listeners.
If you are using #RabbitListener you can add the Channel as a method parameter.
The current 1.7.x release is 1.7.9.

Throttle #JmsListener in spring (prevent TaskRejectedException)

I currently have a JMSListener configured with the following threadpool:
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.initialize();
The queue I'm listening to has well over 100 messages, and when I start the listener it will process the first 10 messages with no problems, and then I will get TaskRejectedException exceptions for the the remaining messages.
My intent is that #JmsListener should not pull any new messages if there are no available threads to process said message. Does anyone know if this configuration is possible? I'm using version 1.5.3 of springboot.
-TIA
If you don't want to lose messages you should not use an executor at all; the container will ack each message as soon as it is queued in the executor. If the system dies, any messages not yet processed will be lost.
Instead, use the container's concurrency settings to multi-thread your listener.
If you really must use an executor and don't mind losing messages, use a caller-runs policy in the executor - setRejectedExecutionHandler().

Resources