0

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:

  1. Is it normal to have instance of message listener container per queue?
  2. Will my message driven pojo (MDP) execute onMessage() on each application node?
  3. If yes, how can I avoid it? I want each message to be consumed once on some of the application nodes.
  4. 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?
liotur
  • 809
  • 2
  • 17
  • 36

1 Answers1

1

See the spring framework JMS documentation and the JMS specification.

  1. Yes it is normal - a container can only listen to one destination.

  2. 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.

  3. See #2.

  4. 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.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I was a bit confused about my second question, because I saw this in doc Asynchronous Reception-Message-Driven POJOs In a fashion similar to a Message-Driven Bean (MDB) in the EJB world, the Message-Driven POJO (MDP) acts as a receiver for JMS messages. The one restriction (but see also below for the discussion of the MessageListenerAdapter class) on an MDP is that it must implement the javax.jms.MessageListener interface. Please also be aware that in the case where your POJO will be receiving messages on multiple threads, it is important to ensure that your implementation is thread-safe. – liotur Jan 06 '19 at 19:51
  • That's just talking about concurrency in the same application instance; if you set to container currency > 1, then multiple consumers are created, each with it's own thread. Therefore, your listener must be thread-safe - no state maintained in fields - or have some synchronization around them (which could limit the actual concurrency if the lock/monitor is held for a long time). When the concurrency is > 1, each consumer competes for messages (the same as when there are multiple app instances). The broker knows nothing about this, he just sees multiple consumers and distributes the messages. – Gary Russell Jan 06 '19 at 20:25
  • Could you please also look at this - https://stackoverflow.com/questions/54169727/multiple-defaultmessagelistenercontainer-for-external-systems – liotur Jan 13 '19 at 16:51