RiaChoi Text Logo.
How Microservices Communicate in Spring Boot

Spring

Zipkin

Eureka

MSA

RabbitMQ

How Microservices Communicate in Spring Boot

Explore core backend concepts in MSA and discover how they communicate with each other.

Ria ChoiMay 18th, 2026

Intro

This post demonstrates how microservices communicate within a Spring Boot application ecosystem.

We will explore key MSA concepts including service discovery with Eureka, distributed tracing with Zipkin, asynchronous messaging through RabbitMQ, and external API communication using OpenFeign, while examining how these technologies work together in a scalable backend architecture.

 

Index

  1. Understanding the Core Concept of Microservice Architecture
  2. Exploring Spring Cloud Infrastructure
    1. Spring Cloud Infrastructure
    2. Eureka Server
      1. What is Eureka Server?
      2. Why Dynamic Infrastructure Matters in MSA
      3. How Eureka Server Works
      4. The Core Function of Eureka Server
    3. Zipkin
      1. What is Zipkin?
      2. Why Do We Need Zipkin?
      3. How Zipkin Works
      4. Distributed Tracing in Microservices
  3. Service Communication in MSA
    1. RabbitMQ and FeignClient
      1. What is RabbitMQ?
      2. Problems with Direct Service-to-Service Communication
      3. Advantages of RabbitMQ
    2. External Communication
      1. OpenFeign
  4. Persistent Layer
    1. About Persistence Layer
    2. The Role
    3. How the Service Layer Communicates with the Persistence Layer
  5. Glossary
  6. Conclusion

 

Understanding the Core Concept of Microservice Architecture

Hub Management System
Hub Management System

 

We’re going to build an AI-featured logistics and delivery management system together in this post.

What this system does is that when a customer places an order, the hub ships the available stock first.

If inventory runs low, the system automatically places a restocking order with the supplier.

In addition, the system sends notifications through Slack, and AI recommends the most efficient delivery route for the delivery agent.

Sounds exciting, right?

 

Now, let’s think about what features we would need to make this system work properly.

The first things that come to mind are Order, Delivery, Hub, and Route services.

On top of that, we can also integrate Slack notifications and AI-powered route recommendations.

To sum it up, the system would include features like these:

List of Services
List of Services

 

In a real-world project, the list would be much longer, but you can already see how quickly it grows!

Imagine a room full of people where everyone has to communicate with each other instantly.

This is why efficient communication between services is so important in large-scale systems like this.

 

Now, let’s move on to another scenario.

Suppose you’re a developer who suddenly needs to fix a critical issue in the delivery service logic.

In a monolithic architecture, even a tiny code change requires rebuilding and redeploying the entire application.

However, in a microservice architecture, services are managed independently, allowing developers to fix issues and deploy only the affected service.

Microservice Architecture (MSA) is an architectural approach that separates services independently, allowing deployment, scalability, and maintenance to be managed more efficiently.

 

If you want to learn more about MSA, you can read my article linked below.

MSA

 

Exploring Spring Cloud Infrastructure

The system we just imagined is actually based on a real project that my team and I built together. Let’s now examine the actual infrastructure design document.

 

If you’d like to learn more about this project, feel free to check out my detailed blog post below.

>> Project Blog Post Link

 

System Architecture Diagram

System Architecture Diagram
System Architecture Diagram

The diagram above shows the actual system architecture we used to build the project.

First, let’s take a look at the large white box at the top of the diagram.

You’ll notice the label Spring Cloud Infrastructure.

As the name suggests, this layer is responsible for managing cloud infrastructure and communication between services.

Now, let’s dive a little deeper into how it works.

 

Spring Cloud Infrastructure

Cloud Infrastructure
Cloud Infrastructure

Eureka Server

What is Eureka Server?
Eureka Server is like a phone book. (I’m not even sure if anyone still remembers what a phone book is)

Without a phone book, you will never know which number to call.

Similarly, in microservice architecture, services need a way to discover and communicate with each other.

 

Normally, API calls use fixed URL addresses.

However, in a microservice architecture, this approach becomes difficult to maintain.

Because services are separated into small independent units, server instances are constantly changing and scaling dynamically.

 

Why Dynamic Infrastructure Matters in MSA

In MSA,

servers can scale up when needed and scale down when demand decreases.

=> In other words, servers in a microservice architecture are resources that can be created or removed at any time.

 

Servers are not managed from a single instance for several important reasons, such as:

  • Traffic handling
  • Stability and reliability
  • Deployment efficiency
  • Failure recovery
  • Cost optimization

Because of these factors, modern systems rely on dynamic infrastructure management rather than static server allocation.

Dynamic Infrastructure Management is the process of automatically scaling, creating, and removing server instances based on system demand.

Static Server Allocation is a traditional infrastructure approach where servers are fixed and manually managed with predefined locations and resources.

 

How Eureka Server Works

1. Register the service in the .yml file

spring:
  application:
    name: delivery-service

→ The delivery-service is now registered with the Eureka Server!

DELIVERY-SERVICE
localhost:8083

Pretty simple, right?

Now we have a server running on port 8083 that is responsible for the Delivery Service.

"Hello, I’m delivery-service,
currently running on port 8083."

Then, whenever another service needs to communicate with it, we ask Eureka:

"Where is delivery-service located?"

2. The order services make a a request

Traditional Approach

http://localhost:8083/api/delivery

Using Eureka

http://DELIVERY-SERVICE/api/delivery

Instead of using a fixed server address, the service name is used.

Eureka then automatically finds the actual server location for the request.

 

The Core Function of Eureka Server

1. Service Registration

Services automatically register themselves with Eureka when they start.

2. Service Discovery

Services can discover the locations of other services dynamically.

3. Health Check

Eureka removes unhealthy or inactive services from the registry.

 

Nowadays, as Kubernetes becomes more widely adopted, many systems use Kubernetes Service Discovery over others.

 

Zipkin

What is Zipkin?

Now that we’ve explored the Eureka section, let’s move on to the orange box on the right.

If you carefully follow the arrows in the diagram, you’ll notice that Zipkin appears at the very end of the request flow.

Both the Service Layer and the Cloud Layer are connected to Zipkin.

From this, we can infer the role of Zipkin in the system.

In a microservice architecture, Zipkin is

A tool used to trace request flows between services.

 

Why Do We Need Zipkin?

In a microservice architecture, a single request usually passes through multiple services.

Order Flow
Order Flow

For example, in our logistics and delivery system, when a customer creates an order, the request flows through several services before the process is completed.

 

‼️ Error Occurs

Now imagine that something goes wrong during this process.

Let’s continue with the same example.

 

Getting 100 coke from supermarket
Getting 100 coke from supermarket

A customer places an order for 100 bottles of cola, but the entire request takes 10 seconds to complete.

Compared to the time it takes to shop at a grocery store, 10 seconds may seem short.

However, in the world of computers, where systems operate in milliseconds or even nanoseconds, 10 seconds is considered a critical performance issue.

 

Now, you are the developer responsible for finding the problem.

To identify where the delay occurred, you would normally have to check

  • Order Service logs
  • Delivery Service logs
  • AI Service logs
  • Slack Notification logs

This means manually searching through logs across multiple services.

However, with Zipkin, you can immediately trace the entire request flow

Gateway                10ms
 └─ Order Service      50ms
     └─ Hub Service    30ms
         └─ AI Service 8700ms  ← Problem Found
             └─ Slack  20ms

As you can see, Zipkin makes it easy to identify that the delay occurred in the AI Service.

 

Service Communication in MSA

Now that we have fully looked through the upper section of the diagram, let’s move on to the next!

Service Logic Layer
Service Logic Layer

When you read the middle box section of the diagram, you notice there are busy lines indicating communications between layers.

How does this communication happen?

 

RabbitMQ and FeignClient

RabbitMQ
RabbitMQ

What is RabbitMQ?

RabbitMQ is a message broker that delivers messages between services.

You can think of it as a postman who delivers data instead of posts.

 

Problems with Direct Service-to-Service

Communication

As you realised by now, in a microservice architecture, the number of services can grow quickly.

In an architecture like this, there could be many problems with using direct API Communication.

 

Let’s bring back the example we talked about earlier.

Order Service
→ Calls Delivery Service
→ Calls AI Service
→ Calls Slack Service

 

1. Tight Coupling 🪢

The Order Service must know

  • The address of the AI Service
  • The address of the Slack Service
  • The address of the Delivery Service

→ This creates strong dependencies between services.

2. Failure Propagation 🫧

Let’s say in our system Slack Service goes down.

One service failure can affect the entire system.

3. Slower Response Time ⏳

If AI analysis or Slack notifications take too long,

→ The customer response also becomes slower

 

But let’s use RabbitMQ 🐇

With RabbitMQ, the flow becomes much simpler.

Order Service
→ Sends only a message:
"Order Created"
RabbitMQ
 ├─ Delivery Service receives the message
 ├─ AI Service receives the message
 └─ Slack Service receives the message

Each service processes the task independently.

This is called asynchronous communication.

 

⭐Core Concept⭐
RabbitMQ Core Concept
RabbitMQ Core Concept

 

Advantages of RabbitMQ 🐰

1. Asynchronous Processing

Users can receive order success responses quickly.

2. Reduce Service Coupling

The Order Service does not need to know who receives the message

→ THis makes services more independent.

3. Failure Isolation

Even if the Slack Service fails, Order creation can still be processed normally.

→ One service failure does not stop the entire system.

4. Large Scale Traffic Handling

Messages can be accumulated in Queues and processed sequentially.

→ This helps the system handle massive traffic more efficiently.

 

External Communication

Now that we’ve explored how services communicate internally, let’s look at how a Spring application communicates with external APIs.

Over time, API calls have become easier, cleaner, and safer to manage.

So, how do we usually call external APIs in Spring?

One common approach is using OpenFeign.

 

OpenFeign

OpenFeign is a Spring Cloud library that allows us to call REST APIs using Java interfaces, without manually writing HTTP request logic.

 

For example, imagine that we need to call the Slack API.

Instead of writing long HTTP request logic with RestTemplate or WebClient, OpenFeign allows us to define the API call in a much cleaner way.

@FeignClient(
    name = "slack-api",
    url = "https://slack.com"
)
public interface SlackClient {

    @PostMapping("/api/chat.postMessage")
    void sendMessage(
        @RequestHeader("Authorization") String token,
        @RequestBody SlackMessageRequest request
    );
}

This code basically tells Spring

Please create an object that can call the Slack API.

 

slackClient.sendMessage(token, request);

When we use this method, Spring turns it into an actual HTTP request.

POST https://slack.com/api/chat.postMessage
Authorization: Bearer xxx

{
  "channel": "delivery",
  "text": "Delivery has started."
}

 

Why Use OpenFeign?

1. Cleaner Code

2. Easier Maintenance

External API logic can be grouped in one place.

For example,

SlackClient
GeminiClient
MapClient

This makes the code easier to read, test, and maintain.

3. Works Well with MSA

OpenFeign is also useful for service-to-service REST communication.

*We can replace RabbitMQ with OpenFeign - this is the traditional way, but I wanted to talk about RabbitMQ here. However, OpenFeign is synchrous by default, so this creates different characteristic between OpenFeign and RabbitMQ.

When used with Eureka, we do not need to write the actual IP address or port.

@FeignClient(name = "delivery-service")

 

*OpenFeign vs RabbitMQ

OpenFeign

Use OpenFeign when you need an immediate result.

  • Inventory lookup
  • User lookup
  • Permission check
  • External API request

RabbitMQ

Use RabbitMQ when the task can be processed asynchronously.

  • Slack notification
  • AI analysis
  • Log storage
  • Background jobs

 

Persistent Layer

Persistence Layer
Persistence Layer

About Persistent Layer

The Persistence Layer is responsible for storing and retrieving data.

=> It is the layer that communicates directly with the database.

Controller Layer
    ↓
Service Layer
    ↓
Persistence Layer
    ↓
Database

 

The Role

1. CRUD Operations

Create, Read, Update, Delete

2. Query Handling

findById(), findAll(), save(), delete()

3. Transaction Management

Maintains database consistency and integrity.

4. JPA and the Persistence Layer

JPA

Jakarta Persistence API (JPA) is a technology that connects Java objects with database tables.

It is commonly used inside the Persistence Layer.

 

Communication Between the Service Layer and Persistence Layer

1. Controller Layer

The Controller only receives the request.

@PostMapping
public void createOrder() {
    orderService.createOrder();
}
2. Service Layer

This is where business logic is handled.

public void createOrder() {

    Order order = new Order();

    orderRepository.save(order);
}

Finally, the service calls orderRepository.save(order);

3. Persistence Layer

Spring Data JPA internally generates and executes SQL queries.

public interface OrderRepository
    extends JpaRepository<Order, Long> {
}

 

Actual Internal Flow 🌊
orderRepository.save(order); - Service Layer
↓
INSERT INTO orders ... - Persistence Layer
↓
Database storage is completed.

 

Glossary 💘

  • MSA (Microservice Architecture) → An architectural style where applications are divided into small independent services.
  • Service Discovery → A mechanism that allows services to dynamically find each other’s locations.
  • Eureka Server → A Service Discovery Server used in Spring Cloud environments.
  • Zipkin → A distributed tracing tool used to track request flows between services.
  • Tracing → The process of tracking how a request moves through multiple services.
  • RabbitMQ → A message broker used for asynchronous communication between services.
  • Asynchronous → A communication method where tasks are processed independently without waiting for immediate responses.
  • Producer → A service that sends messages to RabbitMQ.
  • Consumer → A service that receives messages from RabbitMQ.
  • Queue → A temporary storage space where messages wait to be processed.
  • Exchange → A RabbitMQ component that decides which Queue should receive a message.
  • OpenFeign → A Spring Cloud library that allows REST API calls using Java interfaces.
  • Persistence Layer → The layer responsible for communicating directly with the database.
  • JPA (Jakarta Persistence API) → A Java technology that maps Java objects to database tables.
  • CRUD → Basic database operations: Create, Read, Update, Delete.
  • Loose Coupling → A system design where services have minimal dependency on each other.
  • Scalability → The ability of a system to handle increasing traffic or workload efficiently.

 

Conclusion 🐦‍🔥

Microservice Architecture allows systems to become more scalable, flexible, and maintainable by separating services into independent components.
Technologies like Eureka, Zipkin, RabbitMQ, OpenFeign, and JPA each play important roles in helping large-scale systems communicate efficiently and operate reliably.

 

Share

Related contents

MSAMSA

May 20th, 2026