I'd like to know best practices for consuming messages. I've read MassTransit docs and I've searching about this but I don't get to come to any conclusion.
I have one api (hosting a bus instance) that is publishing messages. These messages are varied because this api is not a microservice (messages for purchases, sales, etc).
How do I have to organize my consumers/queues?
With RabbitMQ, which supports exchanges and queues, messages are sent or published to exchanges and RabbitMQ routes those messages through exchanges to the appropriate queues. When the bus is started, MassTransit will create exchanges and queues on the virtual host for the receive endpoint.
MassTransit provides a heavily production tested convention for using RabbitMQ exchanges to route published messages to the subscribed consumers. The structure is CPU and memory friendly, which keeps RabbitMQ happy.
MassTransit is a lightweight service bus for building distributed . NET applications. The main goal is to provide a consistent, . NET friendly abstraction over the message transport.
Use multiple queues and consumers Queues are single-threaded in RabbitMQ, and one queue can handle up to about 50 thousand messages. You will achieve better throughput on a multi-core system if you have multiple queues and consumers and if you have as many queues as cores on the underlying node(s).
The key concept is to avoid sharing a single queue for different message types. There are exceptions, but keeping each message type on a separate queue prevents bottlenecks when one message type dominates the queue traffic.
As for processes, since MassTransit can have any number of receive endpoints per bus instance, keeping related business functions in a single process can help significantly with code management and deployment. The process boundaries can be useful for scaling, for instance, adding more processes/workers for handling status updates versus new orders (the prior may be 10x the latter in terms of message volume).
Another reason to separate is dependencies, a consumer that communicates with a legacy ERP system with a lot of bindings or coupling to external libraries/SDKs might warrant a separate process just to avoid memory issues due to the way some older libraries are created. These libraries may require more frequent process restarts, etc. and keeping them separate eliminates the need to restart an entire set of consumers for the one that causes issues over time.
These are just some general guidelines, but ones that we use all the time when determining which consumers to put in the same process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With