A comprehensive Java / Spring Boot reference project covering every major distributed system architecture style and design pattern. Each module is a self-contained, runnable example with extensive comments explaining why decisions are made, not just what the code does.
| Layer | Technology |
|---|---|
| Language | Java 17 |
| Framework | Spring Boot 3.2, Spring Cloud 2023.0 |
| Databases | MongoDB (document/BASE), H2 (relational/ACID) |
| Messaging | Apache Kafka |
| Service Discovery | Netflix Eureka |
| API Gateway | Spring Cloud Gateway |
| Resilience | Resilience4j (Circuit Breaker, Retry, Rate Limiter) |
| Service Clients | OpenFeign (declarative HTTP) |
| Build | Maven multi-module |
# Start infrastructure (MongoDB + Kafka)
docker-compose up -d
# Build all modules
mvn clean package -DskipTests
# Run any module
cd 01-client-server/server
mvn spring-boot:runConcept: Simplest distributed model. Server owns all state; clients are thin consumers.
| Component | Port | Description |
|---|---|---|
library-server |
8081 | Spring Boot REST API + MongoDB (Book CRUD) |
library-client |
8082 | RestTemplate client that exercises the server |
Run order: server first, then client.
Key files:
- BookController.java — REST API (the server's contract)
- LibraryClient.java — HTTP client wrapper
- LibraryClientApplication.java — demo runner
Concept: No central server. Every node is simultaneously a client AND a server. Messages gossip across the network.
Run: mvn exec:java -Dexec.mainClass=com.example.distributed.p2p.PeerNetworkDemo
Key files:
- PeerNode.java — dual-role node (server socket + client)
- PeerNetworkDemo.java — 5-node gossip demo
Concepts demonstrated: gossip propagation, fault tolerance (Node-B dies, network still works), decentralisation.
Concept: System divided into strict layers — Presentation → Business → Data.
| Port | App |
|---|---|
| 8083 | student-management-system (MongoDB) |
Key files:
- StudentController.java — Tier 1: HTTP only, no MongoDB
- StudentService.java — Tier 2: business rules (GPA, graduation), no HTTP
- StudentRepository.java — Tier 3: MongoDB only, no business logic
Concept: Loosely coupled, reusable services communicating via REST. OrderService orchestrates InventoryService.
| Component | Port | Description |
|---|---|---|
inventory-service |
8084 | Manages product stock |
order-service |
8085 | Places orders, calls inventory via RestTemplate |
Run order: inventory-service → order-service.
Key files:
- OrderService.java — SOA orchestration: check stock → reserve → persist
- InventoryServiceClient.java — RestTemplate service client
SOA vs Microservices: SOA services can share a database; microservices cannot.
Concept: Fine-grained services, each with its own database, registered with Eureka, routed via API Gateway. Service-to-service calls use Feign (declarative, auto-discovered).
| Component | Port | Description |
|---|---|---|
eureka-server |
8761 | Service registry + dashboard |
api-gateway |
8080 | Single entry point, load-balanced routing |
user-service |
8091 | User profiles (ms_users_db) |
product-service |
8092 | Product catalogue (ms_products_db) |
order-service |
8093 | Orders via Feign (ms_orders_db) |
Run order: eureka → user + product → order → gateway.
Key files:
- UserFeignClient.java — declarative Feign client (no URL, no RestTemplate)
- UserFeignClientFallback.java — fallback when user-service is down
- LoggingFilter.java — cross-cutting concern at gateway
- api-gateway/application.yml — route definitions (
lb://= Eureka lookup)
Database-per-service: each service has its own MongoDB database — ms_users_db, ms_products_db, ms_orders_db.
Concept: Services communicate via Kafka events (pub-sub). Producer fires events; consumers react independently. No direct service calls.
| Port | App |
|---|---|
| 8086 | event-driven-demo |
Kafka Topics: order-events, payment-events, notification-events
Event flow:
POST /api/orders → OrderPlacedEvent (Kafka)
├── InventoryConsumer (group: inventory-group)
├── PaymentConsumer (group: payment-group) → PaymentProcessedEvent
│ └── NotificationConsumer
└── NotificationConsumer (group: notification-group)
Key files:
- OrderPlacedEvent.java — immutable domain event (past tense, versioned, with eventId)
- OrderEventProducer.java — Kafka producer (knows nothing of consumers)
- PaymentEventConsumer.java — consumes then produces a new event (choreography chain)
- NotificationEventConsumer.java — subscribes to two topics
Concept: Demonstrates CP and AP systems side-by-side. Toggle network partition and observe different behaviours.
Strong consistency. On partition: rejects writes (503) rather than risk inconsistency.
POST /api/simulation/partition/on → activate partition
POST /api/bank/transfer → 503 SERVICE_UNAVAILABLE (CP rejects!)
POST /api/simulation/partition/off → restore
POST /api/bank/transfer → success
Key files:
- BankingService.java — SERIALIZABLE isolation + pessimistic locking
- BankAccountRepository.java —
SELECT FOR UPDATEequivalent
Eventual consistency. On partition: serves stale reads rather than go down.
POST /api/simulation/partition/node/REGION_EU → partition EU
PUT /api/catalogue/products/{id}/price → update price on primary
GET /api/catalogue/products?node=REGION_EU → returns STALE price!
POST /api/simulation/heal/node/REGION_EU → heal partition
GET /api/catalogue/products?node=REGION_EU → converged (eventual consistency!)
Key files:
- ReplicationSimulator.java — 3-node simulation with Last-Write-Wins conflict resolution
Distributed transactions without 2PC. Compensation instead of rollback.
POST /api/sagas/orders → OrderSaga: Reserve → Payment → Shipping → Confirm
(or) → Compensate in reverse
Key files:
- OrderSagaOrchestrator.java — the central coordinator with compensation logic
- OrderSaga.java — persisted saga state (crash-safe)
Commands write to H2 (JPA/normalised). Queries read from MongoDB (denormalised).
POST /api/cqrs/orders → writes to H2 + projects to MongoDB
GET /api/cqrs/orders → reads from MongoDB (never H2)
GET /api/cqrs/dashboard → aggregated stats (only possible on read model)
Key files:
- OrderCommandHandler.java — writes to JPA, projects to MongoDB
- OrderQueryHandler.java — reads only from MongoDB
3-node cluster with Bully algorithm leader election. Simulates MongoDB replica set behaviour.
GET /api/cluster/status → see current master
POST /api/cluster/write?key=x&val=y → write to master (replicated)
GET /api/cluster/read?key=x&node=Node-1 → read from slave replica
POST /api/cluster/nodes/Node-3/fail → kill master → watch election!
Key files:
- ClusterNode.java — Bully election, write/read, replication
- ClusterRegistry.java — heartbeat + failure detection scheduler
Resilience4j with three combined patterns: Circuit Breaker + Retry + Fallback.
POST /api/simulation/mode/down → make payment service fail
POST /api/payments/charge (x5) → failures accumulate
POST /api/payments/charge → CB OPENS, fallback returned!
GET /api/circuit-breaker/status → state=OPEN, failureRate=80%
(wait 10s)
POST /api/simulation/mode/normal → restore service
POST /api/payments/charge → success, CB CLOSES
Key files:
- PaymentService.java —
@CircuitBreaker+@Retry+ fallback method - application.yml — CB thresholds, window size, half-open config
| Port | Service |
|---|---|
| 8080 | API Gateway (microservices) |
| 8081 | Library Server (client-server) |
| 8082 | Library Client |
| 8083 | Student Management (multi-tier) |
| 8084 | SOA Inventory Service |
| 8085 | SOA Order Service |
| 8086 | Event-Driven Demo |
| 8087 | CAP CP Example (bank) |
| 8088 | CAP AP Example (catalogue) |
| 8089 | Saga Pattern |
| 8090 | CQRS Pattern |
| 8091 | MS User Service |
| 8092 | MS Product Service |
| 8093 | MS Order Service |
| 8095 | Master-Slave Cluster |
| 8096 | Circuit Breaker |
| 8761 | Eureka Dashboard |
| 9090 | Kafka UI |
| 27017 | MongoDB |
| 9092 | Kafka |
Client-Server
│
└── extends to ──► Multi-Tier (layered roles within the server)
│
└── coarsens to ──► SOA (multiple servers, shared infra)
│
└── refines to ──► Microservices
│
└── adds ──► Event-Driven
CAP Theorem
├── CP: ACID (Oracle, H2) → prefer consistency, sacrifice availability
└── AP: BASE (MongoDB) → prefer availability, accept eventual consistency
Design Patterns
├── Saga → distributed txn without 2PC
├── CQRS → separate read/write models
├── Master-Slave → coordinator + followers
└── Circuit Breaker → resilience against cascading failures