In Microservices, Software Development

A microservices-based application is a distributed system and must use an inter-process communication mechanism. There are two styles of inter-process communication.

Scenario

A very clear scenario that demonstrates this communication between microservices is an eCommerce application that contains Microservices for Orders, Payments, Inventory, and Shipping receives a new order from the user and is trying to process that order.

Asynchronous messaging (indirect)

Asynchronous messaging can be brokered or broker-less. A message broker could lead to business logic leaking from the services into the broker and is against domain driven design and microservice design principals (dump pipes, smart consumers). Broker-less messaging, such as RabbitMQ, are typically used for publishing events that can be consumed by multiple subscribers.

Example

(Order Service) ---> [Order Received] |--> (Payment Service)   |--> [Payment Processed]
                                      |--> (Inventory Service) |--> [Stock Changed]
                                      |--> (Shipping Service)  |--> [Pickup Request]

Order service publishes a message to signal a new event when a new order is received in the system. 3 different services receive a copy of that message and react differently. Payment service starts processing the credit card payment, inventory service reserves the stock quantity required for the order, and shipping service creates a pickup request for the package be shipped to the customer. all events happen simultaneously without direct dependency between the 4 services. this is also a great example of decoupling.

Synchronous messaging (direct)

The other style of inter-process communication is synchronous mechanism such as HTTP. Where services are communicating directly with each other.

Example

Using the same scenario above:

(Order Service) ---> [Process Order] |--> (Payment Service)   |--> [Payment Processed]
(Order Service) ---> [Process Order] |--> (Inventory Service) |--> [Stock Changed]
(Order Service) ---> [Process Order] |--> (Shipping Service)  |--> [Pickup Request]

Another format for the same example could be

(Order Service) ---> [Process Payment] |--> (Payment Service)   |--> [Payment Processed]
(Order Service) ---> [Reserve Stock]   |--> (Inventory Service) |--> [Stock Changed]
(Order Service) ---> [Ship Order]      |--> (Shipping Service)  |--> [Pickup Request]

Order service calls each dependant service to invoke their respective functions in order to fulfil a new order. 3 different services receive a direct call as a result of 1 single operation by the user. all calls are synchronous and explicitly sequenced in the desired order and priority.

This scenario tightly controls the orchestration of workflow between Microservice boundaries. But it also tightly couples the Microservices with direct dependancy on each other.

Summary

A microservice application typically use both asynchronous and synchronous communication patterns for different purpose. It might even use multiple implementations of each style.
Synchronous (blocking) communication are useful when completing a request is dependant on the results of a sub-request from another service that must be awaited. While asynchronous communication is great for raising events to signal something already happened in case other services want to react to, irrespective of any results of such reactions.

Recent Posts
Showing 2 comments
  • Develorem
    Reply

    This is a good basic explanation of the two concepts, but I think some of the terminology is a little off and could confuse newcomers.
    – HTTP is a protocol, just like AMQP is for message queues; how a protocol is used (sync/async) is irrelevant to the protocol itself. AMQP for example supports message acknowledgement which is implemented by RabbitMQ.
    – Async != independent : I can write a heap of async service calls to services I have a direct dependency on, and likewise I can write synchronous calls that leverage RabbitMQ and wait for a message callback response before proceeding (EasyNetQ has some nice ways of handling this).

    When working with Microservices, breaking dependencies is very important, but that doesn’t mean you have to make forced decisions on sync vs async calls.

    • Dot Labs
      Reply

      I understand where the confusion is. The target for this blog post is not a technical reference, but an abstract showcase of the different sync/async patterns. The use of HTTP and AMQP here was to give a relevant example.

Leave a Comment

Contact Us

You can send us an email and we'll get back to you, asap.

Not readable? Change text. captcha txt