The “micro” in microservices refers to a small logical part of a business process that is rarely wholly independent. Typically, multiple microservices interact to complete a task for the application.
For example, a single purchase transaction requires a credit card payment service, an inventory service, a service that manages shipping labels and a service that manages delivery. On top of that, each service needs to execute its function in a very specific order. If one step fails, all the previous steps must roll back, similar to a database transaction. What appears to the software user as one step actually requires dozens of communications and data transfers between microservices.
To address data management issues that emerge in distributed microservices, developers have turned to two distinct coordination styles: orchestration and choreography. Interestingly enough, these two approaches have pushed developers into what is arguably a middle ground between monolithic control and complete independence.
Let’s explore the details of orchestration vs. choreography, including how each approach deals with these complex interactions and what their appropriate use cases are.
Orchestration promotes a centralized approach in which a controller process calls each of the services involved in the transaction, monitors the results and then either calls the next service or performs a rollback. To use the purchase example, the action CreateOrder() appears like a single, logical transaction, but within it the orchestrator manages a complex series of service calls, sometimes called a saga. When the orchestrator aggregates a series of lower-level calls to help build a webpage, it’s called the back ends for front ends pattern.
While orchestration offers tight control of each step in the process, this centralized approach makes services dependent on others. If one service in the chain fails, then the process fails and must start over. Also, if the orchestrator goes down, the whole process fails.
Orchestration is not the only way to solve the saga problem. Services can communicate with each other without any controller. One of the key differences between orchestration and choreography is the asynchronous nature of choreography. Rather than sending a request, blocking and waiting for the response, a web service simply drops a request on the event bus and the bus distributes work between the connected components of an application. Each service works independently and consumes the data that relates to it to perform its task.
For example, consider the events in purchasing an airline ticket. The ticketing service drops a message within the microservices architecture. That message can be picked up by a payment processor, baggage and claim information, a data warehouse, and logistics and planning services, along with the tickets sold service in the app. Because of expected cancellations, airline tickets are routinely oversold — so a delay of a few seconds to a few minutes in posting the reservation may be totally acceptable for the airline and customer. Each associated service is still able to process normally after the change, since it can retrieve the posted message at any time and take the appropriate action independently of the other services.
Choreography can be more complex and difficult to understand than orchestration, because of its decentralized approach. A transaction can go from service to broker to service to broker to service or even have multiple services pick up a message at the same time. These interactions can be hard to track without a centralized orchestrator controlling the transaction end to end. Also, the choreography method is hard to debug and thoroughly test.
Orchestration vs. choreography: Find the right approach
Orchestration and choreography are two distinct approaches for microservices operation, and one may work better than the other for specific business processes.
Orchestration typically works best for services that are transactional or dependent on others to complete a task successfully. On the other hand, choreography is a good fit for work that is asynchronous, runs independently and can be decoupled.
For example, consider the front end to a web service, such as a website for an e-commerce business. That front end may offer users a variety of different web services, such as search, add to cart and checkout. Customer expect a response of some kind when they add an item to the cart. If the application hasn’t picked up that selection message, and added the change to the database yet, the cart will appear empty. That delay, even if it only lasts 30 seconds, can cause confusion, and the customer may add the item again. Now, after the services complete their interactions, there are two items in the cart. The user experience deteriorates when they see these issues.
While choreography enables finely grained services due to high decoupling, sometimes that isn’t really the right architectural decision for the situation. Sometimes, services are more effective when they work like centralized transactions.
When choosing between orchestration and choreography, consider the technical interests of the team and complexity of the environment. Asynchronous programming is a challenging and different way for some teams to think — don’t assume that converting from a sequentially ordered process to an asynchronous one will be simple.
Larger enterprises might do well to consider a hybrid approach, where more services are choreographed, but services with strong dependencies have a controller-based orchestration process. That way, independent services will not fail if services they interact with are down, but the natural dependency is still enforced.