Spring Boot 3 Microservices Orchestrator with Reactive Programming, Apache Kafka

Patroclos Lemoniatis
4 min readMar 25, 2023

--

What is Microservice Orchestration?

In a microservice architecture, orchestration is a central service, where it manages the business logic flow. Think of it as the maestro in an orchestra.

Using orchestrators is essential in an application, for running, managing errors, rollbacks and logging business flows.

Take as example the following microservices in an order management system

★ Order Service

★ Payment Service

★ Inventory Service

Each service-system is autonomous and can be scaled individually without affecting the entire application. As the services grow, business flows become more complex. Consequently it is more difficult to manage this mess.

By using a microservice orchestrator, development teams can focus on building and improving microservices without worrying about the complexities of deployment and management. Additionally, a microservice orchestrator can help ensure the overall reliability, and availability of the entire distributed system.

Orchestration vs Choreography

While both are widely used for microservices architecture, orchestration is difficult to implement, while choreography is the opposite. Orchestration is strongly coupled while Choreography is loosely coupled and more scalable. Handling failures in Choreography is risky where each Microservice is handling error in its own specific way.

That being said,

for handing and managing complex processes, which require central logging and auditing, we will be better off using the Orchestration approach.

Orchestration Saga Pattern

Managing transactions in distributed systems can become very messy in situations where a lock could be held on a table for a long time, until the other processes finish and respond.

While a 2 phase commit transaction could be used in this case, there is a drawback regarding it’s synchronous nature.

The Saga pattern is asynchronous and reactive. The transaction in this pattern are executed in asynchronous local database transactions, without affecting the availability of the database data, avoiding database deadlocks.

Reactive programming

It is a design paradigm which effectively relies on asynchronous code logic to provide updates. It provides reactive streams to handle the chain of events for code logic to be executed.

Such a library is https://projectreactor.io/

Apache Kafka

In order to be able to publish and consume events we need a Message broker[server]. Apache Kafka is an open-source streaming platform. It is operating as a publish-subscribe message queue like RabbitMQ. It is used for messaging, metrics collection, monitoring, logging, event sourcing and real-time analytics.

There as 3 key differences from traditional Messaging platforms

  • It uses a cluster, thus it can scale to handle many applications
  • It is using a local store to persist messages even when the messages have been already consumed and acknowledged by the consumer
  • Handles stream processing, computing derived streams and datasets dynamically rather in a batch

In our case, lets use Kafka for a high throughput of messages, in addition to the replay capabilities and the permanent message storage in contrast to the RabbitMQ.

Real case scenario

Lets take a look at a scenario where a customer wants to create an order

  • Step 1. Customer adds an order request
  • Step 2. Orchestrator service listens to the event and starts the process of confirming customer payment, product item stock availability and stock deduction.
  • Step 3. If all steps are completed successfully, the Orchestrator service will publish an event for updating the order.
  • Step 4. Order service consumes the event and updates the order status.

Let’s say, the customer does not have enough money to pay for the order

  • Step 1. Customer adds an order request
  • Step 2. Orchestrator service listens to the event and starts the process of confirming customer payment and product item stock availability.
  • Step 3. Payment step fails and Orchestrator service is publishing an update event for order cancellation.
  • Step 4. Order service consumes the event and updates the order status.

What is achieved,

is the execution of a ‘complex’ -although this is just an example- process, where we have a central Log for process step execution. In case of failure, the process steps failed, along with the corresponding error, are recorded in the Orchestrator database. This makes troubleshooting way easier, plus this can be used as a central Audit Log as well. Execution of steps is asynchronous, so no need to block user experience from the frontend, while waiting for process completion.

In conjunction with the use of reactive streams the processes are executed with non-blocking back pressure, therefore Orchestrator is able to handle a huge amount of requests simultaneously.

Please find an example demonstrating this case scenario architecture, in the link below

Source code built with Spring Boot 3, using Apache Kafka

https://github.com/patroklos83/Microservices-Orchestrator-Saga-Pattern

--

--