A review of microservice orchestration frameworks
Microservice orchestration helps create complex processes in products. To avoid programming these mechanics manually, developers can use ready-made frameworks that contain microservice management tools. We have examined this topic and want to discuss three such frameworks.
We have already written about transaction management in microservice architecture — why it’s necessary and what difficulties it tackles. When a complex business process is being automated, the product can involve several microservices simultaneously. And while it's quite simple to arrange the interaction of several modules within a monolith, in a distributed architecture, where each component is a separate app, challenges arise.
The microservice orchestrator manages the process execution. Hence no data is lost; it gets easier for support to fix problems and for developers to manage the entire system's development.
Such a module can be written from scratch or a ready-made framework can be used. Such frameworks are a must if a company has several developer teams. First, programmers don't have to do the same job time and again. Second, uniform work standards appear when everyone uses the same tools; this immediately affects the quality of products. Instead of reinventing the wheel, everyone is focusing on developing a common tool.
Orchestration framework architecture
The framework includes out-of-the-box orchestration components. These are the orchestrator itself, which accepts tasks and hands them over to working microservices for execution.
When a product launches a process (for instance, managing a journey on a website), the orchestrator generates a task queue to be implemented by the microservices. In our case, it could be an "Air ticket purchase," "Hotel reservation," or "Car rental." The microservices pick up these tasks and report on the progress. The data is stored in the orchestrator's own storage so that, if the process is suddenly interrupted, it can be resumed from the same stage.
Now for how we selected and compared different frameworks:
What demands we had for the orchestrator
Process simplicity. We require a convenient environment in which microservice interaction will be shown clearly. An extra benefit would be automatic document generation when an orchestration description becomes the entire system's description.
Error processing. In case of a malfunction, it should be possible to set up the number of retries and timeouts. Moreover, business logic setup and microservice mechanics should be independent so that they could be run separately, and that changing a business process would not break the entire product. Besides, the Saga design pattern support is utilized — so it's necessary to provide for rollback actions when the process stops at some step.
Support for asynchronous activities and workflows. It’s necessary to save interim data, to simplify development, and to make performance more stable in general.
Multiplatform support. It’s desirable that the tool could be used by all teams at once (for example, we are developing in Java and .NET).
Framework comparison
We studied existing tools and selected three candidates that fit our criteria. They have similar capability sets, yet implementation differs a bit.
Netflix Conductor. Business process and activity parameters are described in JSON files. In the microservices' code one has to write unique strings by which the orchestrator will address them. Business logic setup for each individual activity is available.
Camunda Zeebe. Camunda is a BPMN engine that we have long been using (for example, to orchestrate our tracker with a customer's tracker or to automate business processes). If you know Camunda, then the Zeebe interface will be quite familiar to you too. Its main advantage is a dedicated graphics editor which is easy for non-developers to figure out. Data is stored in XML files.
Temporal. Pure code is used for orchestration. There are no identifiers — microservices are called via code or their own interface, which must be additionally outlined. For many developers it will be the easiest and most conventional of all.
Comparison results based on our criteria:
- Process simplicity. Zeebe has proved to be the most illustrative thanks to its graphical component. And Temporal is the most conventional for developers due to orchestration via code.
- Error processing. The capabilities of all the frameworks are approximately the same, yet Zeebe is a bit weaker. Among the critical parameters, it only enables the configuration of the number of retries, and doesn't support Saga without duct tape.
- Support for asynchronous activities. Everyone is equally good here.
- Multiplatform support. All frameworks develop the Java clients, and .NET versions are supported by the community.
Conclusion
The comparison shows that there is no silver bullet — each framework is good in its own way. A tool should be selected through a dialog with the teams — someone may be more comfortable dealing with JSON, another will prefer visualization, and the third will want to use pure code.
Yet any framework is better than embedding orchestration into each product's code separately. Otherwise, developers have to research the mechanics from scratch every time and overload the code. Adding to that, uniform standards will appear across the whole company, and help bring all your teams to a common development platform.