Communication between microservices using a Business Event Based approach via an Event Broker Service
When integrating Microservices, the principle of “independence” means that it is desirable to avoid directly coupling the services. A commonly used technique is to use a message queue to provide the integration required, as shown:
When Service A needs to integrate with another service, a new queue is used:
Now, let’s give these services some example names, say Service A is the Customer Service, and B and C are the Order and CRM services respectively. The message passed is the customer entity details. The Order service needs to know about the customer details, and the CRM service also needs to be updated with the same info. The picture now looks like:
Ok, this all looks fine, and is a sensible way of integrating the services without directly coupling them. Now let’s add in a few more services and entities that would contribute to an Order, say Catalog Item and Address Services. This requires queues for each of these entities. To keep the diagram tidy let’s move the message entity name onto the queues. We now have the components of an order feeding into the Order Service and the customer details being passed to (e.g.) the CRM system:
Of course, it would probably be necessary to pass the order details to the CRM service so another queue between order and CRM is required, like so:
So far so good. Now, let’s say add a requirement to integrate the order service with another MI Reporting service. This needs another instance of an Order Details Queue:
We are starting to suffer from proliferation of duplicate queues. As we add more services to the mix the problem increases almost exponentially with every new service.
If we switch to a publish-subscibe pattern rather than point to point queues, we eliminate this duplication. To make effective use of a Pub-Sub model it is helpful to think in terms of “business events” and use an event broker pattern to mediate between services. So each service no longer talks directly to a queue, but talks instead to the broker publisher service to publish an event, e.g. “New Order Placed”. That changes our picture to look like this:
If we move the other service integrations into the broker so all communications are mediated by it then the picture looks like this:
Let’s focus on the Business Event “New Order Placed”. When the order is completed the Order service raises an event that an new order had been placed. This event would be passed to the broker which would notify all services that had subcribed to the event. So in our example workflow, let’s say that the “New Order Placed” event is subcribed to by a Packing Service so the order can be packaged, a CRM Service so the customer relations team can assist the customer with a follow up email, and a Reporting Service so the management can keep see the ordering levels being updated in real time.
The Packing Service would then trigger a new business event “Order Packed” which would be passed back to the Order service, to store the new order status, and update the CRM Service and Reporting Service with the current Order status. It would also notify the “Dispatch Service” that an order was packed and hence ready for dispatch.
The Order would be physically dispatched and the dispatch service updated to indicate the new order status. The Dispatch Service would then trigger a new business event “Order Dispatched” which would be passed back to the Order service, to store the new order status, and update the CRM Service and Reporting Service with the new Order status..
So in the placing of an order the sequence diagram would be as shown:
See my next post for an example of how to implement an Event Broker in Azure: https://rolandkamsika.com/index.php/2020/04/14/microservice-event-driven-communication-part-2/
All examples and code by Roland Kamsika