A production-ready microservices architecture built with Spring Boot 3.5, Spring Cloud, and comprehensive observability.
Client
↓
API Gateway (8080) ← Circuit Breakers
↓
Eureka Discovery (8761)
↓
┌─────────────┬──────────────┬──────────────┐
│ │ │ │
User Service Product Service Order Service
(8081) (8082) (8083)
│ │ │
PostgreSQL PostgreSQL PostgreSQL
(5432) (5433) (5434)
-
Eureka Server (Port 8761)
- Service Discovery and Registration
- Health monitoring of all services
-
API Gateway (Port 8080)
- Single entry point for all client requests
- Load balancing with Eureka
- Circuit breakers for resilience
- Request routing and filtering
-
User Service (Port 8081)
- User management and authentication
- CRUD operations for users
- PostgreSQL database (port 5432)
-
Product Service (Port 8082)
- Product catalog management
- Inventory tracking
- PostgreSQL database (port 5433)
-
Order Service (Port 8083)
- Order processing
- Inter-service communication with User & Product services
- Circuit breakers and retry mechanisms
- PostgreSQL database (port 5434)
-
Prometheus (Port 9090)
- Metrics collection from all services
- Time-series database
-
Grafana (Port 3000)
- Visualization dashboards
- Metrics analysis
- Default credentials: admin/admin
- Java 17
- Spring Boot 3.5.6
- Spring Cloud 2024.0.0
- PostgreSQL 16
- Flyway - Database migrations
- Resilience4j - Circuit breakers, retry, rate limiting
- Prometheus & Grafana - Monitoring and observability
- SpringDoc OpenAPI - API documentation
- Lombok - Reduce boilerplate
- Docker & Docker Compose - Containerization
- ✅ Service Discovery (Eureka)
- ✅ API Gateway (Spring Cloud Gateway)
- ✅ Circuit Breaker (Resilience4j)
- ✅ Retry Pattern
- ✅ Load Balancing
- ✅ Health Checks
- ✅ Database per Service
- ✅ Centralized Monitoring
- ✅ JWT authentication & authorization
- ✅ BCrypt password encryption
- ✅ Role-based access control
- ✅ Database migrations with Flyway
- ✅ Global exception handling
- ✅ Request validation
- ✅ Structured logging
- ✅ Prometheus metrics
- ✅ Grafana dashboards
- ✅ Docker containerization
- ✅ Kubernetes deployment
- ✅ Health checks for all services
- Java 17 or higher
- Gradle 8.x
- Docker & Docker Compose
- Kubernetes (optional)
- Git
-
Clone the repository
git clone <your-repo-url> cd Microservice
-
Start PostgreSQL databases
docker-compose up -d userdb productdb orderdb
-
Build all services
./gradlew clean build
-
Run services in order
# 1. Start Eureka Server ./gradlew :eureka-server:bootRun # 2. Start API Gateway (in new terminal) ./gradlew :api-gateway:bootRun # 3. Start business services (in new terminals) ./gradlew :user-service:bootRun ./gradlew :product-service:bootRun ./gradlew :order-service:bootRun
-
Build all services
./gradlew clean build
-
Start entire stack
docker-compose up -d
-
Check service health
docker-compose ps
-
View logs
# All services docker-compose logs -f # Specific service docker-compose logs -f user-service
-
Stop all services
docker-compose down
-
Stop and remove volumes
docker-compose down -v
For production deployments on Kubernetes, see the complete guide in k8s/README.md
Quick Start:
-
Build and push Docker images
# Build all services ./gradlew clean build # Build Docker images (replace YOUR_REGISTRY) docker build -t YOUR_REGISTRY/eureka-server:latest eureka-server docker build -t YOUR_REGISTRY/api-gateway:latest api-gateway docker build -t YOUR_REGISTRY/user-service:latest user-service docker build -t YOUR_REGISTRY/product-service:latest product-service docker build -t YOUR_REGISTRY/order-service:latest order-service # Push to registry docker push YOUR_REGISTRY/eureka-server:latest docker push YOUR_REGISTRY/api-gateway:latest docker push YOUR_REGISTRY/user-service:latest docker push YOUR_REGISTRY/product-service:latest docker push YOUR_REGISTRY/order-service:latest
-
Update deployment manifests
Edit all YAML files in
k8s/deployments/to use your registry. -
Deploy to Kubernetes
cd k8s ./deploy.sh # Linux/Mac # or deploy.bat # Windows
-
Access services
# Get API Gateway URL kubectl get svc api-gateway -n microservices # Port forward (for local testing) kubectl port-forward svc/api-gateway 8080:8080 -n microservices
What's Deployed:
- ✅ Namespace isolation
- ✅ StatefulSets for PostgreSQL with persistent volumes
- ✅ Deployments with auto-scaling ready
- ✅ Service discovery via Kubernetes DNS
- ✅ Ingress controller for routing
- ✅ Prometheus & Grafana monitoring
- ✅ Resource limits and health checks
- API Gateway: http://localhost:8080
- Eureka Dashboard: http://localhost:8761
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
Base URL: http://localhost:8080/api/users
# Create User
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"password": "password123"
}'
# Get All Users
curl http://localhost:8080/api/users
# Get User by ID
curl http://localhost:8080/api/users/1
# Get User by Email
curl http://localhost:8080/api/users/email/john@example.com
# Update User
curl -X PUT http://localhost:8080/api/users/1 \
-H "Content-Type: application/json" \
-d '{
"email": "john.updated@example.com",
"firstName": "John",
"lastName": "Doe",
"password": "newpassword123"
}'
# Delete User
curl -X DELETE http://localhost:8080/api/users/1Base URL: http://localhost:8080/api/products
# Create Product
curl -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d '{
"sku": "LAPTOP-001",
"name": "MacBook Pro",
"description": "16-inch laptop",
"price": 2499.99,
"stockQuantity": 50
}'
# Get All Products
curl http://localhost:8080/api/products
# Get Available Products
curl http://localhost:8080/api/products/available
# Get Product by ID
curl http://localhost:8080/api/products/1
# Get Product by SKU
curl http://localhost:8080/api/products/sku/LAPTOP-001
# Update Product
curl -X PUT http://localhost:8080/api/products/1 \
-H "Content-Type: application/json" \
-d '{
"sku": "LAPTOP-001",
"name": "MacBook Pro M3",
"description": "16-inch laptop with M3 chip",
"price": 2699.99,
"stockQuantity": 45
}'
# Update Stock
curl -X PATCH "http://localhost:8080/api/products/1/stock?quantity=-5"
# Delete Product
curl -X DELETE http://localhost:8080/api/products/1Base URL: http://localhost:8080/api/orders
# Create Order
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"items": [
{
"productId": 1,
"quantity": 2
},
{
"productId": 2,
"quantity": 1
}
]
}'
# Get All Orders
curl http://localhost:8080/api/orders
# Get Order by ID
curl http://localhost:8080/api/orders/1
# Get Order by Order Number
curl http://localhost:8080/api/orders/number/ORD-202501-A1B2C3D4
# Get Orders by User ID
curl http://localhost:8080/api/orders/user/1
# Update Order Status
curl -X PATCH "http://localhost:8080/api/orders/1/status?status=SHIPPED"
# Cancel Order
curl -X DELETE http://localhost:8080/api/orders/1Each service has its own Swagger UI:
- User Service: http://localhost:8081/swagger-ui.html
- Product Service: http://localhost:8082/swagger-ui.html
- Order Service: http://localhost:8083/swagger-ui.html
Access Prometheus at http://localhost:9090
Sample Queries:
# HTTP request rate
rate(http_server_requests_seconds_count[5m])
# Circuit breaker states
resilience4j_circuitbreaker_state
# JVM memory usage
jvm_memory_used_bytes
- Access Grafana at http://localhost:3000
- Login with admin/admin
- Import Spring Boot dashboards (IDs: 4701, 11378, 12900)
# API Gateway
curl http://localhost:8080/actuator/health
# User Service
curl http://localhost:8081/actuator/health
# Product Service
curl http://localhost:8082/actuator/health
# Order Service (includes circuit breaker health)
curl http://localhost:8083/actuator/health# 1. Create a user
USER_RESPONSE=$(curl -s -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"firstName": "Test",
"lastName": "User",
"password": "password123"
}')
USER_ID=$(echo $USER_RESPONSE | jq -r '.id')
# 2. Create products
PRODUCT1=$(curl -s -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d '{
"sku": "PROD-001",
"name": "Product 1",
"description": "Test product",
"price": 99.99,
"stockQuantity": 100
}')
PRODUCT1_ID=$(echo $PRODUCT1 | jq -r '.id')
# 3. Create an order (tests inter-service communication)
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d "{
\"userId\": $USER_ID,
\"items\": [
{
\"productId\": $PRODUCT1_ID,
\"quantity\": 2
}
]
}"# 1. Stop Product Service
docker-compose stop product-service
# 2. Try to create an order (should fail with circuit breaker fallback)
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"items": [
{"productId": 1, "quantity": 1}
]
}'
# 3. Check circuit breaker state
curl http://localhost:8083/actuator/health
# 4. Restart Product Service
docker-compose start product-serviceMicroservice/
├── eureka-server/ # Service Discovery
├── api-gateway/ # API Gateway with Circuit Breakers
├── user-service/ # User Management Service
├── product-service/ # Product Catalog Service
├── order-service/ # Order Processing Service
├── monitoring/
│ ├── prometheus/ # Prometheus config
│ └── grafana/ # Grafana provisioning
├── docker-compose.yml # Full stack orchestration
├── build.gradle # Root build config
├── settings.gradle # Multi-module settings
└── README.md
- Check Eureka dashboard at http://localhost:8761
- Verify service logs:
docker-compose logs -f <service-name> - Ensure services started after Eureka
# Check database status
docker-compose ps
# Restart databases
docker-compose restart userdb productdb orderdb# Check circuit breaker events
curl http://localhost:8083/actuator/circuitbreakerevents
# Reset by restarting the service
docker-compose restart order-service-
Add Security
- Spring Security with OAuth2/JWT
- Service-to-service authentication
-
Add Message Queue
- Kafka or RabbitMQ for async communication
- Event-driven architecture
-
Add Distributed Tracing
- Micrometer Tracing with Zipkin/Tempo
- Request correlation across services
-
Add Config Server
- Centralized configuration management
- Dynamic config refresh
-
Add API Rate Limiting
- Resilience4j rate limiter
- Per-user quota management
-
Add Caching
- Redis for distributed caching
- Cache aside pattern
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the MIT License.