Spring JMS DefaultMessageListenerContainer - receive n messages per 1 sec - jms

I need to receive 'n' number of messages per every second from IBM MQ. Example : I need to receive maximum 10 messages per second.
I want to use DefaultMessageListnerContainer of spring.
Can this be achieved by setting the below configurations?
<bean id="msgListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:connectionFactory-ref="mqConnectionFactory"
p:messageListener-ref="myMessageListener"
p:concurrentConsumers="1"
p:maxConcurrentConsumers="10"
p:receiveTimeout="1000"
p:maxMessagesPerTask = "10" />

You might be better using JmsTemplate.receiveAndConvert() instead of a message-driven architecture, if you want to control the rate of message consumption.

Spring DMLC doesn't have a throttle built in. Apache Camel is another option that is designed for JMS -> throttle -> data processing

Related

Control consumption of multiple JMS queues

I can't find this information anywhere. I have two queues, #JmsListener(destination = "p1"), #JmsListener(destination = "p2"). How can I make sure I only process 1 message at a time, even though I am listening to 2 queues, and also how do I configure the polling of what queue I get messages from first, that is after processing a message I want to poll p1 first. Or do weighted polling: p1:90%, p2:10%. Etc.
Basically I am asking how to implement priority processing of messages for Spring. I'm using SQS which doesn't support priorities.
Use one of the JmsTemplate receive() or receiveAndConvert() methods instead of the message-driven model.
Use transactions if you want to ensure no message loss.

synchrous message listener jms

I have one doubt during my work with JMS. As I know it's possible to create synchrous message consumer. However, I must launch it with a frequency, because of the fact that there is no listener. Next, to consume messages synchrously from a queue I can create a MDB and set the pool to 1. I think it is not a good solution.
My aim is to consume messages synchrously when they appear on the queue. From my point of view above mentioned solutions are not good:
1. Consumer which is launched from time to time.
2. MDB (asynchrous normally) and pool is set to 1.
Are there any solutions for my purpose?
Not sure why you don't like MDBs... but if you want to avoid them, you could use the Spring JMS listener:
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/jms.html

Message Scheduling/Consumption in JMS based on Defined Time

We are using IBM WebSphere MQ as JMS provider with Spring MDP (Message Driven POJO).
Is there any way in JMS where we can configure time related properties in message so that message can be consumed at particular defined time only?
For example, if I am sending three messages into queue M1, M2 and M3. Where, I can configure M2 message property let say 3 AM. And consumer side, consumer can only pick this message # 3 AM only. If time is not defined, messages should be consumed in a way that JMS Receiver does.
JMS 2.0 specification has defines Delivery Delay. With this feature a message producer can specify that a message must not be delivered until after a specified time interval. The message will be available for delivery after the specified time. But this may not help you as you want to a message to be consumed at a specified time. Typically messaging applications are designed to consume messages as soon as they are made available by the messaging provider.
If you want to process messages at a specified time only, you could create another queue "queue_3am", and schedule a reader to run exactly at 3am.
A variation is to set the timestamp as a message property. So one queue could contain messages to be processed at different points in time. The reader could use message selectors to get relevant messages only.
But you should use a "message pickup timeframe" by adding two timestamps as message properties, for eaxmple set the window to 1 or 5 minutes.
The receiver can use a message selector: A selector is a condition using message properties.
Have a look at this

Concurrency value in JMS topic listener in Spring

I know Spring but I am a newbie in JMS and started reading the Spring JMS. From the Spring JMS doc Spring doc, I read the following
The number of concurrent sessions/consumers to start for each listener.
Can either be a simple number indicating the maximum number (e.g. "5")
or a range indicating the lower as well as the upper limit (e.g. "3-5").
Note that a specified minimum is just a hint and might be ignored at
runtime. Default is 1; keep concurrency limited to 1 in case of a topic
listener or if queue ordering is important; consider raising it for
general queues.
Just want to understand why should the concurrency limited to 1 in case of a topic listener? If I increase it, say to 10 instead of 1, what would happen?
Each subscriber receives a copy of each message published to a Topic. It makes no sense at all to put up multiple consumer, since all your application would do is to receive the same message 10 times, in different threads.
In the case of a Queue, messages on the queue would be distributed among 10 threads and hence, handled concurrently. That is indeed a very common scenario - load balancing.

Making EJB MessageDrivenBean work like DefaultMessageListenerContainer (JMS, OpenMQ)

I am using the Spring DefaultMessageListenerContainer to gain some dynamic benefits in setting the MessageSelector value since I am using the Glassfish OpenMQ which is not that advanced in that regards.
Let's have a JMS message. The listener issues a specific failure that means: retry after x seconds. It tries again with failure: retry after x*y seconds, and so on the time grows exponentially. If you cannot handle it after z retries, consider it as a poison JMS message.
DefaultMessageListenerContainer dmlc;
dmlc.stop();
dmlc.setMessageSelector(String.format("retries < %d AND retryTime <= %d", z, System.currentTimeMillis()));
dmlc.start();
I am not that satisfied with this solution, especially, when the Spring docs raise warning here:-). However, for the moment things meet our needs.
Now, I have a number of EJBs message consumers on different applications. Some of them need such dynamic changes of the messageSelector. Unfortunately, and to-my-best-knowledge, EJB MDBs do not support such dynamic "features". For example, see this.
Is that correct? is there a workaround for an EJB solution? I would appreciate any help.
To achieve dynamic changes to the message selector, you'd need to implement it straight in JMS, e.g.
ConnectionFactory cf;
Connection connection = cf.createConnection();
session = connection.createSession(transactional, acknowledgeMode);
MessageConsumer messageConsumer = session.createConsumer(destination, "message selector");
Additionally, you'd need to place this code some place it executes on its own, perhaps in an asynchronous task? But you'd be reinventing the wheel, as Spring DMLC does that better.
I don't know why you're doing this:
for load balancing? The message broker should take care of this.
for handling temporary downtimes? The queue should be configured to be able to store appropriate number of messages, or switch delivery to other node in cluster.

Resources