Microservices Architecture - Fundamentals of Distributed System Design

18 min read | 2025.12.19

What are Microservices

Microservices architecture is a design approach that builds applications as a collection of small, independent services. Each service has a single responsibility and can be deployed and scaled independently.

Large-scale web services like Netflix, Amazon, and Uber have adopted this architecture.

Difference from Monolith: In monolithic architecture, all functionality is contained in a single application. In microservices, functionality is divided into separate services.

From Monolith to Microservices

flowchart TB
    subgraph Monolith["Monolithic Architecture"]
        subgraph SingleApp["Single Application"]
            Auth1["Auth"]
            Product1["Product"]
            Order1["Order"]
            Payment1["Payment"]
        end
        SharedDB["Shared Database"]
        SingleApp --> SharedDB
    end
flowchart TB
    subgraph Micro["Microservices Architecture"]
        subgraph AS["Auth Service"]
            Auth2["Auth"] --> DB1["DB"]
        end
        subgraph PS["Product Service"]
            Product2["Product"] --> DB2["DB"]
        end
        subgraph OS["Order Service"]
            Order2["Order"] --> DB3["DB"]
        end
        subgraph PaS["Payment Service"]
            Payment2["Payment"] --> DB4["DB"]
        end
    end

Microservices Design Principles

1. Single Responsibility Principle

Each service specializes in one business function.

Good ExamplesBad Example
Auth Service: Login, token managementUser Service: Auth + Profile + Notifications + Settings → Too many responsibilities
Product Service: Product info, inventory management
Order Service: Order processing, history management

2. Autonomy

Services should be deployable and operable independently without depending on other services.

3. Distributed Data Management

Each service owns its data and doesn’t directly access other services’ databases.

4. Fault Isolation

Design so that failure of one service doesn’t cascade to the entire system.

Service Communication Patterns

Synchronous Communication (REST/gRPC)

flowchart LR
    Client --> Gateway["API Gateway"] --> A["Service A"] --> B["Service B"]

Service A waits for response from Service B

  • REST API: Simple, HTTP-based
  • gRPC: Efficient communication via Protocol Buffers

Asynchronous Communication (Message Queue)

flowchart LR
    A["Service A"] --> MQ["Message Queue<br/>(RabbitMQ, Kafka)"] --> B["Service B"]

Responds immediately, processes later

  • Event-driven: Achieves loose coupling between services
  • Reliability: Message persistence and redelivery

Approaches to Service Decomposition

Domain-Driven Design (DDD)

Divide services by Bounded Contexts.

E-commerce example:

Product ContextOrder ContextCustomer ContextPayment Context
ProductOrderCustomerPayment
CategoryOrder ItemAddressBilling
InventoryShipping

Decomposition Criteria

CriteriaDescription
Business boundariesSeparate different business domains
Change frequencyIsolate frequently changing parts
Scale requirementsIsolate high-load functions
Team structureDivide by team responsibility

Microservices Challenges and Solutions

Distributed System Complexity

ChallengeSolution
Network failuresCircuit breaker, retries
Data consistencySaga pattern, event sourcing
Service discoveryService discovery (Consul, Eureka)
Monitoring difficultyDistributed tracing (Jaeger, Zipkin)

Circuit Breaker Pattern

StateFlowResult
NormalClient → Service A → Service BNormal response
Failure (circuit open)Client → Service A ✕ Service B (failed)Fallback response (cached or default value)

When to Choose Microservices

Suitable cases

  • Large teams wanting parallel development
  • Need for different tech stacks per service
  • Need to scale specific features independently
  • Domains that can be clearly separated

Not suitable cases

  • Small-scale applications
  • Small teams (5 or fewer people)
  • Insufficient domain knowledge
  • Immature operations infrastructure

Monolith First: Starting with a monolith and breaking into microservices as you grow is often the recommended approach.

Summary

Microservices is a powerful architectural pattern for managing complexity in large-scale systems. However, it comes with distributed system-specific challenges. It’s important to consider team size, business complexity, and operational capabilities when choosing the appropriate architecture.

← Back to list