spring-boot-starter-amqp will works between micro services? - spring-boot

I am new to Spring amqp.
I have tried to send the messages by following: https://spring.io/guides/gs/messaging-rabbitmq/
I am able to send the messages within the micro services.
But unable to send the messages to another micro services ? Is it expected ?
If I want to send the messages between the micro services which dependency I should follow ?
Please help me here.

What you want is something like this (figure taken from a recent blog post of mine, which also shows more detailed code examples):
Here, as an example, CRUD-Events like "customer.created" or "order.deleted" are considered
Any microservice can act as an Event Producer and send events to an event exchange via RabbitTemplate, which is provided by Spring AMQP and can just be injected into any Spring Bean.
A cluster of instances of the same microservice share a queue.
The consuming microservices declare their queue and the binding between queue and event exchange by declaring #Beans of type Queue and Binding with the same attributes.
The binding defines which events will be received by each microservice cluster
All microservices must share the same event exchange by declaring a #Bean of type Exchange with the same exchange name.

In one service you would send the message and in an other receive it. In the example you now have both in 1 project. In the sending service you have the RabbitTemplate and in the other service the Receiver with the SimpleMessageListenerContainer and MessageListenerAdapter beans. Make sure that the binding, queue and exchange configuration are the same and the services are both connected to the same RabbitMQ server.

Related

PCF app connecting to Spring AMQP - different messaging service after binding app to RabbitMQ service

I am new to PCF and need some help understanding the root cause of an issue I am facing.
We have one PCF application that is connecting to Rabbit MQ (no binding done on the Rabbit MQ service yet). the messages get passed through the application to queues created on this Rabbit MQ instance. so far so good.
But when we bind again the application to the same Rabbit MQ instance and restage the application, it starts getting connected to a different messaging instance and the message is being relayed to that messaging service and no message transfer happened on expected Rabbit MQ instance although I can't see the actual movement of messages because I might not be having access to the mystery messaging service (I say that because two spring boot services are communicating as expected and the process gets completed).
I am clueless as to what is changing in the application by binding it to Rabbit MQ. is it a default spring implementation of spring AMQP which is interfering here? what can I do to stop this behavior? I haven't provided any parameters while binding the app to Rabbit MQ.
I tried to put the loggers to find out the name of the exchange it's getting connected to but it's still the same exchange, but I can't see the messages flowing and can't explain the phenomenon to the client.
Try to look at the service key of the your rabbit instance and that will give you hostname etc. i.e. rabbitmq details where you are connecting to after binding.
cf service-key SERVICE_INSTANCE SERVICE_KEY
Not sure if there is any default setting in the app that's being used for setting up the connection to a different rabbit instance in absence of binding.

Event Driven Architecture on Multi-instance services

We are using microservice architecture in our project. We deploy each service to a cluster by using Kubernetes. Services are developed by using Java programming language and Spring Boot framework.Three replicas exist for each service. Services communicate with each other using only events. RabbitMQ is used as a message queue. One of the services is used to send an email. The details of an email are provided by another service with an event. When a SendingEmail event is published by a service, three replicas of email service consume the event and the same email is sent three times.
How can I prevent that sending emails by other two services?
I think it depends on how you work with Rabbit MQ.
You can configure the rabbit mq with one queue for these events and make spring boot applications that represent the sending servers to be "Competing" Consumers.
If you configure it like this, only one replica will get an event at a time and only if it fails to process it the message will return to the queue and will become available to other consumers.
From what you've described all of them are getting the message, so it works like a pub-sub (which is also a possible way of work with rabbit mq, its just not good in this case).

Configuring multiple queues with a topic exchange and using routing key to direct the message specific queue with spring cloud streams

Configuring multiple queues with a topic exchange and using routing key to direct the message specific queue with spring cloud streams
My requirement is example I have the queues and exchange defined as below in consumer end
spring.cloud.stream.bindings.inputA.destination=Common-Exchange
spring.cloud.stream.bindings.inputA.group=A-Queue
spring.cloud.stream.bindings.inputB.destination=Common-Exchange
spring.cloud.stream.bindings.inputB.group=B-Queue
I should be able to specify the routing key in the consumer just like
we do it in AMQP where we can pass the exchange queue and routing key
to create the binding
I should be able to set the routing key when sending the message in
producer end using MessageBuilder
channel.send(MessageBuilder.withPayload(message).build())
Of course we can use one queue and use headers to direct different type of messages but I need to know how multiple queue connected to a single exchange work with streams.
See the Rabbit binder documentation.
On the consumer side, set the bindingRoutingKey consumer binding property.
On the producer side, the the routingKeyExpression producer binding property (e.g. headers['routingKey'] and set that header as needed).
Also see Using Existing Queues/Exchanges.

Use SimpMessagingTemplate without creating a web socket message broker Spring 4

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.

How to get properly all queue messages from RabbitMQ in Spring?

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.

Resources