i am using the Amazon SQS as Message Queue. I am investigating how it is possible to set up a Spring consumer within Tomcat that would consume messages. However i looked around and it seems to say that to deploy a Spring Message Driven Bean to consume messages from Queue in Tomcat, i would need TomcatEE / Tomcat + ActiveMQ.
At the same time i have also reviewed the following SQS-Spring driver and wonder if it is of much use. http://nevado.skyscreamer.org/quickstart.html
Could someone advise what is required to accomplish the above?
SimpleMessageListenerContainer can be used to start/stop listeners programatically.
simpleMessageListenerContainer.start("logical queue name")
Other than that you have two options. Using spring's QueueMessagingTemplate
Message<?> msg = ((QueueMessagingTemplate) template).receive("logical queue name");
this will requiere that no listeners are defined in the application for this queue.
Or use the spring cloud messaging annotation SQSListener
#SqsListener(value = "logical queue name")
Related
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.
I am trying to configure concurrent consumers in spring to consume messages from RabbitMQ, in order to achieve that i have configured consumers in two ways
1.annotated a method with #RabbitListener(queues = "name of queue")
2.implementing "MessageListener" interface and overriding onMessage(Message message)
In my case both the ways worked fine, but i am unable to figure out what is the advantage/disadvantage of using #RabbitListener() for starting a consumer over the other way.
Also adding to that i have configured "DirectMessageListenerContainer" in my configuration and mapped it to "MessageListener" implementation to achieve concurrent consumers, my question here is can we do the same mapping for consumer implemented through #RabbitListener() and if so how. I couldnt find any source on how a consumer started with a #RabbitListener() annotated method can be configured with a "DirectMessageListenerContainer"
Any Help is appreciated.
#RabbitListener is simply a higher-level abstraction. It uses the listener container underneath.
When using spring boot, use the ...listener.type application property to specify which type of container you want.
The default is simple.
We have built a Spring Boot messaging service that listens to a JMS queue hosted on a TIBCO EMS (Enterprise Messaging Service) Server. It is a fairly straightforward application that receives a JMS message, does some data manipulation and updates a database.
The issue is that, occasionally, there are no JMS consumers on the queue, and incoming messages are not processed. However the Spring Boot app is up and running (verified by ps -ef). Restarting the app restores the consumer, but unfortunately this is not a feasible solution in production etc.
Other facts of interest:
We have observed this to happen when the JMS server accepts SSL traffic and is on deployed as a Fault Tolerant pair (although this has been a conculsive observation yet)
There is absolutely no indication in the log (like an error) when the consumer goes down.
We are using Spring-JMS (4.1.0) and TIBCO EMS (8.3.0)
Code Snippet of instantiating a DefaultJmsListenerContainerFactory:
#Bean
public DefaultJmsListenerContainerFactory listenerJmsContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
TibjmsQueueConnectionFactory cf = new TibjmsQueueConnectionFactory("tcp://localhost:7222");
cf.setUserName("admin");
cf.setUserPassword("");
factory.setConnectionFactory(cf);
return factory;
}
The JMS Listener:
#JmsListener(destination = "queue.sample", containerFactory = "listenerJmsContainerFactory")
public void listen(TextMessage message, Session session) throws JMSException{
System.out.println("Received Message: "+message.getJMSMessageID());
System.out.println("Acknowledgement Mode: "+session.getAcknowledgeMode());
// Some more application specific stuff
}
While we are trying to setup additional logging on both the Spring Boot and TIBCO side, we would like to check some points like:
Can there be a situation where a consumer idle for more than a certain time, automatically expires?
Is this something that is governed by DMLC settings like idleConsumerLimit, idleTaskExecutionLimit etc.?
Can these properties be viewed in the Spring Boot code mentioned above? For instance in the code above, the JMS Listener is being created under the hood by the DefaultJmsListenerContainerFactory. So how can we access the DMLC object so that we can invoke methods like getIdleConsumerLimit(), getIdleTaskExecutionLimit() etc.
Thanks for the inputs,
Prabal
Most likely, something in the network (router, firewall etc) is silently dropping idle connections.
While not part of the JMS spec, most vendors implement some kind of heartbeat mechanism so that the client/server exchange pings from time to time, to prevent such actions by network components and/or to detect such conditions.
Look at the Tibco documentation to figure out how to configure heartbeats (they might call it something else).
Can I send a message to a message broker using SimpMessagingTemplate#convertAndSendToUser or SimpMessagingTemplate#convertAndSend methods without settings up a websocket message broker using #EnableWebSocketMessageBroker?
What I'm trying to do is utilise one websocket server to provide messaging for two application server instances(One spring 4 and one Spring 3). I created a one web server with Spring 4, Spring boot plus websocket message broker enabled.
Now I want two application servers to push messages to rabbitmq so it will broadcast them to clients subscribed to it.
First issue I faced is if there is no websockt message broker configuration available, SimpMessagingTemplate will not get autowired to application context. I couldn't get it injected without creating a websocket message board either.
Please help me to find out whether this is possible.
BTW I have a previous question unanswered related to this.
Well, After reading lots of documentation I found the answer myself. The key thing is this architecture is following.
In this architecture spring act as a gateway for communication between the message broker and client. Spring doesn't do anything(Other than when it necessary) but forward the request to the message broker(STOMP messages). The configuration kept on Spring defines couple of important things. One is the exchange and other were routing keys. Spring configuration gives us an abstract layer so we subscribe and push messages to message broker without a fuss.
SimpMessagingTemplate is the abstract layer which we use to communicate with message broker. Spring creates the bean using the given details. Well I couldn't create a instance of SimpMessagingTemplate manually. I have to update Spring 3 application to Spring 4 in order to use websockets.
Since Spring and message broker is decoupled, clustering the application instance doesn't make any effect on message broker. Spring will communicate to message broker only when it need to subscribe to a channel or when it need to publish a message to a channel. So if there is two instances subscribing to same channel it would be two queues binding the one exchange using same routing key. Messages published into a channel will be available to all subscribers(queues) because they all use same routing key. Refer to rabbitmq stop plugin documentation for more elaborative description.
I am using Spring, Spring-Websocket, STOMP for my application, and RabbitMQ as broker. I need to log all messages going through RabbitMQ to Postgresql tables.
I know that I can write #MessageMapping in Spring and log there, but my problem is that some clients talk to RabbitMQ directly through MQTT protocol, and Spring does not support it yet (https://jira.spring.io/browse/SPR-12581). Moreover browser clients talk through Spring to RabbitMQ using STOMP protocol.
RabbitMQ allows to track all messages using Firehose tracer. How to properly listen to amq.rabbitmq.trace topic from Spring? Or do I need to write separate Java app as consumer?
The Spring AMQP is for you!
You bind some custom queue to to that amq.rabbitmq.trace with appropriate pattern (e.g. publish.#) and configure SimpleMessageListenerContainer to receive messages from that queue.
It can be done even with pretty simple config: #EnableRabbit and #RabbitListener on some POJO method. Anyway the Binding #Bean must be there to attache your queue to that exchange.