RabbitMQ architecture to manage trips and coordinates - spring-boot

I'm new to RabbitMQ, but I know that my use case fits well in this kind of architecture. What I want to achieve is the following.
Using an android application, the user will push the "start trip" button. This will call to an API which will create the trip. Then, the android application will send data periodically, gps coordinates, to the API (which will accomplish some task). When the user finishes the trip, another call to the API will be made.
Until now, the API was a simple Restful written using spring boot. Now, I want to make changes to the architecture and add RabbitMQ.
I've thought that whenever a trip is started, the API will create a Queue (queue_trip_XXX, as XXX is the trip identificator), bound to a exchange (trips_exchange) with a routing key (trip_XXX). Then, but dynamically, gps coordinates will be sent to the exchange and routed to the corresponding queue. When the user ends the trip, the queue will be removed.
So, there will be one queue for each trip and a unique exchange. Is this appropriate? Do you have any other solution that would best fit to this use case?
Another question is how can I create a consumer which listens to messages sent to a queue?
Thanks!

So, there will be one queue for each trip and a unique exchange. Is this appropriate?
As I've mentioned in the comment I don't think it's a good idea due to the fact that every queue in RabbitMQ is a separate Erlang process.
Is there any reason why you would like to process messages from one trip separately from the others? Maybe one queue will be enough for start?
Another question is how can I create a consumer which listens to messages sent to a queue?
I assume you already have two nodes (one for API and one for RabbitMQ broker).
You should just create the third one which will be responsible for processing the data.

Related

MassTransit Multiple Consumers

I have an environment where I have only one app server. I have some messages that take awhile to service (like 10 seconds or so) and I'd like to increase throughput by configuring multiple instances of my consumer application running code to process these messages. I've read about the "competing consumer" pattern and gather that this should be avoided when using MassTransit. According to the MassTransit docs here, each receive endpoint should have a unique queue name. I'm struggling to understand how to map this recommendation to my environment. Is it possible to have N instances of consumers running that each receive the same message, but only one of the instances will actually act on it? In other words, can we implement the "competing consumer" pattern but across multiple queues instead of one?
Or am I looking at this wrong? Do I really need to look into the "Send" method as opposed to "Publish"? The downside with "Send" is that it requires the sender to have direct knowledge of the existence of an endpoint, and I want to be dynamic with the number of consumers/endpoints I have. Is there anything built in to MassTransit that could help with the keeping track of how many consumer instances/queues/endpoints there are that can service a particular message type?
Thanks,
Andy
so the "avoid competing consumers" guidance was from when MSMQ was the primary transport. MSMQ would fall over if multiple threads where reading from the queue.
If you are using RabbitMQ, then competing consumers work brilliantly. Competing consumers is the right answer. Each competing consume will use the same receive from endpoint.

Howto find out all the subscribed to filters in a PUB server?

I have a PUB server. How can it tell what filters are subscribed to, so the server knows what data it has to create?The server doesn't need to create data once no SUB clients are interested in.
Say the set of possible filters is huge ( or infinite ), but subscribers at any given time are just subscribed to a few of them.
Example: Say SUB clients are only subscribed to a weather feed data for a few area codes in New York and Paris. Then the PUB server shouldn't have to create weather data for every other area code in every other city in the world, just to throw it all away again.
How do you find out all the subscribed to filters in a PUB server?
If there is no easy way, how do I solve this in another way?
I'll answer my own question here in case its of use to anyone else.
The requirements where:
The client should be able to ask the server what ids (topics) are available for subscription.
The client should chooses the id's it is interested in and tell the server about it.
The server should created data for all subscribed too id's and send that data to clients.
The client and server should not block/hang if either one goes away.
Implementation:
Step 1. Is two way traffic, and is done with REQ/REP sockets.
Step 2. Is one way traffic from one client to one server, and is done by PUSH/PULL sockets.
Step 3. Is one way traffic from one server to many clients, and is done by PUB/SUB sockets.
Step 4. The receives can block either the server or client if the other one is not there. Therefore I followed the "lazy pirate pattern" of checking if there is anything to receive in the queue, before I try and receive. (If there is nothing in the queue I'll check again on the next loop of the program etc).
Step 4+. Clients can die without unsubscribing, and the server wont know about it, It will continue to publish data for those ids. A solution is for the client to resends the subscription information (with a timestamp) every so often to the server. This works as a heartbeat for the ids the client has subscribed too. If the client dies without unsubscribing, the server notices that some subscription ids have not been refreshed in a while (the timestamp). The server removes those ids.
This solution seems to work fine. It was a lot of low level work though. It would be nice if zeromq was a bit higher level, and had some common and reliable architectures/frameworks ready to use out of the box.

(How) can i route a message to one particular client?

I'm trying to understand the principles of HornetQ as well as core/JMS messaging using this solution.
In my experimental app, I'd like my end-user application(client) to send messages to a HornetQ which will be read by a backend app. So far this is no problem and I love HornetQ.
But now, i'd like to send an "answer" message from the backend app back to the end-user. For this, I have the condition that no other client app should be able to read the answer message (let's say it contains the current bank balance). So user A should only fetch messages for himself and the same applies to any other user.
Is this possible using HornetQ? If so, how do I have to do it?
with hornetq (or any other message system) you always send to a queue, not to a specific consumer.
ON this case you have to create a queue matching your client.
This answer here will provide you some feedback on request-response where I won't need to repeat myself after this approach:
Synchronous request-reply pattern in a Java EE container

JMS Producer-Consumer-Observer (PCO)

In JMS there are Queues and Topics. As I understand it so far queues are best used for producer/consumer scenarios, where as topics can be used for publish/subscribe. However in my scenario I need a way to combine both approaches and create a producer-consumer-observer architecture.
Particularly I have producers which write to some queues and workers, which read from these queues and process the messages in those queues, then write it to a different queue (or topic). Whenever a worker has done a job my GUI should be notified and update its representation of the current system state. Since workers and GUI are different processes I cannot apply a simple observer pattern or notify the GUI directly.
What is the best way to realize this using a combination of queues and/or topics? The GUI should always be notified, but it should never consume anything from a queue?
I would like to solve this with JMS directly and not use any additional technology such as RMI to implement the observer part.
To give a more concrete example:
I have a queue with packages (PACKAGEQUEUE), produced by machine (PackageProducer)
I have a worker which takes a package from the PACKAGEQUEUE adds an address and then writes it to a MAILQUEUE (AddressWorker)
Another worker processes the MAILQUEUE and sends the packages out by mail (MailWorker).
After step 2. when a message is written to the MAILQUEUE, I want to notify the GUI and update the status of the package. Of course the GUI should not consume the messages in the MAILQUEUE, only the MailWorker must consume them.
You can use a combination of queue and topic for your solution.
Your GUI application can subscribe to a topic, say MAILQUEUE_NOTIFICATION. Every time (i.e at step 2) PackageProducer writes message to MAILQUEUE, a copy of that message should be published to MAILQUEUE_NOTIFICATION topic. Since the GUI application has subscribed to the topic, it will get that publication containing information on status of the package. GUI can be updated with the contents of that publication.
HTH

point to point JMS and publish and subscribe

I have a basic question about, the JMS architecture. A typical arrangement can be point-to-point, were message from customers are interleaved. that means that concurrent communication is not supported right?
now in publish and subscribe we can have lots of customers registered in one or more topics, and each time a message is sent all the registered customers receive the message right?
(i guess it is done by using multicast right?)
if i wanted to implement JMS for sending queries to a database, and receive responses from the database, then the publish and subscribe method should be used right? I can't do it with point - to - point, if i have multiple client right?
You can do it with point to point, you just probably wouldn't want to.
For database interactions, you probably want a data grid, not a message queue - and you can use temporary queues if you really are desperate to fit JMS into the architecture.
I guess I have a question for you: what exactly are you trying to accomplish?

Resources