Skip to content

Latest commit

 

History

History
698 lines (588 loc) · 15.3 KB

File metadata and controls

698 lines (588 loc) · 15.3 KB

🚀 Deployment Guide - Spring Cloud Microservices

📋 Table of Contents

  1. Prerequisites
  2. Local Development Setup
  3. Docker Deployment
  4. Production Deployment
  5. Monitoring & Health Checks
  6. Troubleshooting

🛠️ Prerequisites

System Requirements

  • Java: OpenJDK 11 or higher
  • Maven: 3.6+ for building applications
  • Docker: 20.10+ and Docker Compose 2.0+
  • Memory: Minimum 8GB RAM (16GB recommended)
  • Storage: 10GB free space

Development Tools

  • IDE: IntelliJ IDEA, VS Code, or Eclipse
  • Git: For version control
  • Postman: For API testing
  • Docker Desktop: For container management

Verify Installation

# Check Java version
java -version

# Check Maven version
mvn -version

# Check Docker version
docker --version
docker-compose --version

# Check available memory
docker system info | grep -i memory

💻 Local Development Setup

1. Clone Repository

git clone <repository-url>
cd Spring-Cloud-Microservices

2. Build All Services

# Build all services
mvn clean package -DskipTests

# Or build individual services
cd user-service && mvn clean package -DskipTests
cd order-service && mvn clean package -DskipTests
cd notification-service && mvn clean package -DskipTests

3. Start Infrastructure Services

# Start databases and message broker
docker-compose up -d postgres mongodb redis rabbitmq

# Verify infrastructure is running
docker-compose ps

# Note: Zipkin, Prometheus, and Grafana are also available
docker-compose up -d zipkin prometheus grafana

4. Start Microservices Locally

# Terminal 1 - Eureka Server
cd eureka-server
mvn spring-boot:run

# Terminal 2 - API Gateway (wait for Eureka to start)
cd api-gateway
mvn spring-boot:run

# Terminal 3 - User Service (uses H2 database locally)
cd user-service
mvn spring-boot:run

# Terminal 4 - Order Service
cd order-service
mvn spring-boot:run

# Terminal 5 - Notification Service
cd notification-service
mvn spring-boot:run

# Terminal 6 - Admin Dashboard
cd admin-dashboard
mvn spring-boot:run

# Optional - Zipkin Server (registers with Eureka, but use Docker Zipkin for UI)
cd zipkin-server
mvn spring-boot:run

5. Automated Local Startup

# Use provided script for automated startup
.\start-services.bat

# Check service health
.\check-services.bat

🐳 Docker Deployment

1. Quick Docker Start

# Build and start all services
.\start-docker.bat

# Or manually
docker-compose up --build

2. Docker Compose Configuration

Infrastructure Services:

# docker-compose.yml (Infrastructure)
services:
  postgres:
    image: postgres:15
    restart: unless-stopped
    environment:
      POSTGRES_DB: microservices_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres123
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 15s
      timeout: 5s
      retries: 5

  mongodb:
    image: mongo:6
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: admin123
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db

  rabbitmq:
    image: rabbitmq:3-management-alpine
    restart: unless-stopped
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: admin123
    ports:
      - "5672:5672"
      - "15672:15672"

Microservices:

# docker-compose.yml (Services)
  eureka-server:
    build: ./eureka-server
    restart: unless-stopped
    ports:
      - "8761:8761"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8761/actuator/health"]
      interval: 15s
      timeout: 5s
      retries: 5

  user-service:
    build: ./user-service
    restart: unless-stopped
    ports:
      - "8081:8081"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/microservices_db
    depends_on:
      eureka-server:
        condition: service_healthy
      postgres:
        condition: service_healthy

3. Docker Build Optimization

Multi-stage Dockerfile:

# Dockerfile for each service
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

# Add health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD curl -f http://localhost:8081/actuator/health || exit 1

EXPOSE 8081
ENTRYPOINT ["java", "-jar", "app.jar"]

4. Docker Management Commands

# View running containers
docker-compose ps

# View logs
docker-compose logs -f user-service
docker-compose logs -f --tail=100

# Scale services
docker-compose up -d --scale user-service=3

# Stop services
docker-compose down

# Clean up (remove volumes)
docker-compose down -v

# Rebuild specific service
docker-compose build user-service
docker-compose up -d user-service

🏭 Production Deployment

1. Kubernetes Deployment

Namespace Setup:

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: microservices
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: microservices-config
  namespace: microservices
data:
  eureka.url: "http://eureka-server:8761/eureka/"
  postgres.url: "jdbc:postgresql://postgres:5432/microservices_db"
  mongodb.url: "mongodb://mongodb:27017/notifications"
  rabbitmq.url: "amqp://admin:admin123@rabbitmq:5672"

Service Deployment:

# user-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
  namespace: microservices
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: microservices/user-service:1.0.0
        ports:
        - containerPort: 8081
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "kubernetes"
        - name: EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE
          valueFrom:
            configMapKeyRef:
              name: microservices-config
              key: eureka.url
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8081
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8081
          initialDelaySeconds: 30
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: microservices
spec:
  selector:
    app: user-service
  ports:
  - port: 8081
    targetPort: 8081
  type: ClusterIP

Ingress Configuration:

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: microservices-ingress
  namespace: microservices
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - api.microservices.com
    secretName: microservices-tls
  rules:
  - host: api.microservices.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-gateway
            port:
              number: 8080

2. Auto-scaling Configuration

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: user-service-hpa
  namespace: microservices
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: user-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

3. Database Migration

Production Database Setup:

-- Production PostgreSQL setup
CREATE DATABASE microservices_prod;
CREATE USER microservices_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE microservices_prod TO microservices_user;

-- Create tables
\c microservices_prod;

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    role VARCHAR(20) DEFAULT 'USER',
    status VARCHAR(20) DEFAULT 'ACTIVE',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);

Flyway Migration:

-- V1__Create_users_table.sql
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    role VARCHAR(20) DEFAULT 'USER',
    status VARCHAR(20) DEFAULT 'ACTIVE',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- V2__Add_indexes.sql
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);

4. Environment Configuration

Production Application Properties:

# application-production.yml
spring:
  datasource:
    url: ${DATABASE_URL}
    username: ${DATABASE_USERNAME}
    password: ${DATABASE_PASSWORD}
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
  
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false
    properties:
      hibernate:
        format_sql: false
        use_sql_comments: false

  redis:
    host: ${REDIS_HOST}
    port: ${REDIS_PORT}
    password: ${REDIS_PASSWORD}
    timeout: 2000ms
    jedis:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5

eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_URL}
    registry-fetch-interval-seconds: 30
  instance:
    lease-renewal-interval-in-seconds: 30
    lease-expiration-duration-in-seconds: 90

logging:
  level:
    com.microservices: INFO
    org.springframework: WARN
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{36} - %msg%n"

📊 Monitoring & Health Checks

1. Health Check Endpoints

# Service Health Checks
curl http://localhost:8761/actuator/health  # Eureka
curl http://localhost:8080/actuator/health  # API Gateway
curl http://localhost:8081/actuator/health  # User Service
curl http://localhost:8082/actuator/health  # Order Service
curl http://localhost:8083/actuator/health  # Notification Service
curl http://localhost:8090/actuator/health  # Admin Dashboard

2. Metrics Collection

# Prometheus Metrics
curl http://localhost:8081/actuator/prometheus

# Specific Metrics
curl http://localhost:8081/actuator/metrics/jvm.memory.used
curl http://localhost:8081/actuator/metrics/http.server.requests

3. Distributed Tracing

# Zipkin Traces
curl http://localhost:9411/api/v2/traces

# Service Dependencies
curl http://localhost:9411/api/v2/dependencies

4. Log Aggregation

ELK Stack Configuration:

# docker-compose-monitoring.yml
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"

  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline
    ports:
      - "5044:5044"
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.0
    ports:
      - "5601:5601"
    environment:
      ELASTICSEARCH_HOSTS: http://elasticsearch:9200
    depends_on:
      - elasticsearch

🔧 Troubleshooting

1. Common Issues

Service Registration Problems:

# Check Eureka server logs
docker logs eureka-server

# Verify service configuration
curl http://localhost:8761/eureka/apps

# Check network connectivity
docker exec user-service ping eureka-server

Database Connection Issues:

# Check database status
docker logs microservices-postgres

# Test connection
docker exec -it microservices-postgres psql -U postgres -d microservices_db

# Check connection pool
curl http://localhost:8081/actuator/metrics/hikaricp.connections.active

Memory Issues:

# Check container memory usage
docker stats

# Check JVM memory
curl http://localhost:8081/actuator/metrics/jvm.memory.used

# Increase container memory
docker-compose up -d --scale user-service=0
docker-compose up -d user-service

2. Performance Tuning

JVM Tuning:

# Dockerfile optimization
ENV JAVA_OPTS="-Xms512m -Xmx1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Database Optimization:

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 60000

3. Backup & Recovery

Database Backup:

# PostgreSQL backup
docker exec microservices-postgres pg_dump -U postgres microservices_db > backup.sql

# MongoDB backup
docker exec microservices-mongodb mongodump --db notifications --out /backup

# Restore PostgreSQL
docker exec -i microservices-postgres psql -U postgres microservices_db < backup.sql

Configuration Backup:

# Backup Docker volumes
docker run --rm -v microservices_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres_backup.tar.gz /data

# Backup application configs
cp -r ./config ./backup/config-$(date +%Y%m%d)

🎯 Deployment Checklist

Pre-deployment

  • All tests passing
  • Security scan completed
  • Performance testing done
  • Database migrations ready
  • Configuration validated
  • Monitoring setup verified

Deployment

  • Infrastructure services started
  • Database migrations applied
  • Services deployed in correct order
  • Health checks passing
  • Load balancer configured
  • SSL certificates installed

Post-deployment

  • All services registered with Eureka
  • API endpoints responding
  • Database connections working
  • Message queues operational
  • Monitoring dashboards active
  • Logs being collected
  • Backup procedures tested

This comprehensive deployment guide covers all aspects of deploying the Spring Cloud microservices from local development to production environments, including monitoring, troubleshooting, and best practices.