One common task is to make sure that services react to relevant events. Instead of polling you can tie your system together using async events.
Another usage is to handle long running tasks without the user waiting on them. Say for instance that you fire off an event or a command once an offer is requested. There might be potentially many integrations involved in a business flow, why it then makes sense to return early with a first message to the potential client “We are processing your request”, then you could send email and server side sent event to the user once you have finished processing.
Having message queue allows you decouple services. If you publish an event, there isn’t a strict need for a specific receiver. This allows you to start work on “basket” service before a “catalog” service is fully finished (then wire up logic to deal with inconsistencies later on).
Masstransit wraps common message queues and presents you with an uniform API. This is similar to what we have with entity framework for SQL.
RabbitMQ et.c. throws away the messages after they have been successfully processed. If you want to be able replay old events, then this is not for you.
Masstransit (and similar wrappers) makes assumptions about how you want to deal with failures, what kind of format and how send vs publish works. This can mean that there are some discrepancies when implementing publishers and receivers in other languages than C#. Going towards a more heterogenous environment you will probably need to invest more into getting to know your message queue. In a previous project there was a need to invest in adjusting an AMQP wrapper for nodejs since the existing wrapper was out of date and did not implement the correct error handling. There is a Java port where the author mentions that he only needed a subset of features available from Masstransit in Java.
If you want to send out events on a very granular high volume, say each time someone views a page on a very popular site, then this is probably not for you. You should look at alternatives like Kafka.
Transaction lock on multiple databases is a known costly affair. There are a couple of options of dealing with this. One way is to have a really large database so that the transaction is over a single database. Another way is to use the saga pattern to avoid those issues. Note for instance The Coffee Shop OrderStateMachine.
Another way is to think about data in a slightly different way: For instance by storing events and later on generate the resulting relational view of data at one point in time.
If you are on Azure then Azure Service bus is simple to setup. There are also NuGet packages to use Masstransit with AmazonSQS and ActiveMQ but these are more recent than the RabbitMQ and Azure Service bus packages. Easiest way to start locally is to use RabbitMQ by writing a docker-compose file:
version: '3.4' services: rabbitmq: image: rabbitmq:3-management-alpine ports: - "15672:15672" - "5672:5672"
Masstransit is open source and free. RabbitMQ requires hosting. See AWS and Azure for pricing of their offerings.
Masstransit (and similar) allows you to wire up loosely coupled distributed mediator. Since Masstransit allows you to use either RabbitMQ, AWS or Azure native message queues it is fairly easy to have it up and running. It is a leaky abstraction when you are going towards a heterogenous environment (but reimplementing subsets of Masstransit can be good enough).
Do you want to send a comment or give me a hint about any issues with a blog post: Open up an issue on GitHub.
Do you want to fix an error or add a comment published on the blog? You can do a fork of this post and do a pull request on github.