java5 min read

Spring Cloud Tutorial: Learn Microservices from Scratch (2026)

Spring Cloud Tutorial: Learn Microservices from Scratch (2026)

Published:  |  Category: Java  |  Reading time: ~15 min
Spring Cloud Tutorial: Learn Microservices from Scratch (2026)

Spring Cloud provides tools for building distributed systems — service discovery, configuration management, circuit breakers, API gateways, and distributed tracing. Building microservices is easy; operating them reliably at scale is hard. Spring Cloud addresses the hard parts. I have used it to build platforms spanning dozens of services across multiple data centers, and the patterns it implements are battle-tested in production.

This tutorial covers service registration and discovery, distributed configuration, load balancing, circuit breakers, API gateways, and distributed tracing. Each pattern solves a specific distributed-systems challenge.

Service Discovery with Netflix Eureka

In a microservice architecture, services come and go dynamically. Eureka provides service registration and discovery: each service registers with the Eureka server and periodically sends heartbeats. Clients discover service instances by querying Eureka by application name, enabling load balancing and failover without hardcoded URLs.

Run a Eureka server as a Spring Boot application with @EnableEurekaServer. Client services use @EnableDiscoveryClient and the DiscoveryClient interface to locate peers. For resilience, run multiple Eureka servers in peer-awareness mode.

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryServerApplication.class, args);
    }
}

// application.yml for Eureka server
eureka:
  instance:
    hostname: eureka-primary
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

// Client configuration
spring:
  application:
    name: order-service
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-primary:8761/eureka/

Distributed Configuration with Spring Cloud Config

Externalizing configuration for each service across environments is a logistics problem. Spring Cloud Config Server serves configuration from a Git repository, Vault, or JDBC database. Services fetch their configuration at startup and optionally refresh it without restart via @RefreshScope and Spring Cloud Bus.

Store configuration files named {application}-{profile}.yml in a Git repository. The config server exposes these as REST endpoints. Use native profiles for fast local development and Git-backed config for consistency across environments.

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

# application.yml
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/company/config-repo
          searchPaths: '{application}'
          default-label: main

# Bootstrap config for clients
spring:
  application:
    name: order-service
  cloud:
    config:
      uri: http://config-server:8888
      fail-fast: true
      retry:
        max-attempts: 5

Load Balancing with Spring Cloud LoadBalancer

Client-side load balancing distributes requests across available service instances. Spring Cloud LoadBalancer replaces the older Netflix Ribbon. It integrates with RestTemplate (via @LoadBalanced) and WebClient. Load balancing is aware of service discovery — it gets instance lists from Eureka and applies a round-robin or random strategy.

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@Service
public class OrderService {
    private final RestTemplate restTemplate;

    public InventoryResponse checkInventory(OrderRequest request) {
        // "inventory-service" resolves via Eureka and round-robins
        return restTemplate.getForObject(
            "http://inventory-service/api/stock/{sku}",
            InventoryResponse.class,
            request.sku()
        );
    }
}

Circuit Breakers with Resilience4j

Microservices depend on other services. When a dependency fails or slows down, the failure cascades. Circuit breakers monitor failure rates and open the circuit after a threshold, failing fast instead of waiting for timeouts. Resilience4j is the recommended circuit breaker library for Spring Cloud (replacing Hystrix).

Configure circuit breaker thresholds, timeouts, and fallback methods via annotations or Java DSL. Combine with retry, rate limiter, and bulkhead for comprehensive resilience.

@Service
public class PaymentService {
    @CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackPayment")
    @Retry(name = "paymentService", fallbackMethod = "fallbackPayment")
    @TimeLimiter(name = "paymentService")
    public CompletableFuture processPayment(PaymentRequest request) {
        return CompletableFuture.supplyAsync(() ->
            paymentGateway.charge(request));
    }

    public CompletableFuture fallbackPayment(
            PaymentRequest request, Throwable t) {
        log.warn("Payment fallback: {}", t.getMessage());
        return CompletableFuture.completedFuture(
            new PaymentResponse(request.orderId(), PaymentStatus.FAILED, t.getMessage()));
    }
}

API Gateway with Spring Cloud Gateway

An API gateway is the single entry point for all client requests, handling routing, authentication, rate limiting, and header transformation. Spring Cloud Gateway is a reactive (WebFlux-based) gateway that routes requests via predicate matching (path, header, query param) and applies filters.

Define routes in YAML or Java DSL. Common filters: AddRequestHeader, StripPrefix, Retry, CircuitBreaker, and RequestRateLimiter. The gateway integrates with Eureka for service discovery.

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
            - name: CircuitBreaker
              args:
                name: orderCircuitBreaker
                fallbackUri: forward:/fallback/orders
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

Distributed Tracing with Micrometer Tracing

Debugging performance issues in a distributed system requires tracing requests across service boundaries. Micrometer Tracing (replacing Spring Cloud Sleuth) adds trace IDs and span IDs to logs and propagates them via headers. Configure sampling rate to control observability overhead.

Integrate with Zipkin, Jaeger, or OpenTelemetry collectors for trace visualization. In your logs, the trace ID correlates all log entries for a single request across services.

spring:
  application:
    name: order-service
  tracing:
    sampling:
      probability: 0.1  # 10% of requests

# Log pattern includes trace/span IDs
logging.pattern.level: '%5p [%X{traceId:-}--%X{spanId:-}]'

Frequently Asked Questions

When should I use Spring Cloud vs Kubernetes-native tools?

Spring Cloud is ideal when you want framework-level integration without Kubernetes. If you already run Kubernetes, use its built-in service discovery (DNS), ConfigMaps, and Ingress controllers — they are more platform-agnostic.

What is the difference between Eureka and Consul?

Both provide service discovery. Eureka is focused on availability (AP in CAP theorem) and eventually consistent. Consul offers health checking, key-value storage, and multi-datacenter support (CP, strongly consistent).

How do I handle distributed transactions across services?

Avoid distributed transactions (2PC) in microservices. Use the Saga pattern — a sequence of local transactions with compensating actions for rollback. Orchestrate sagas with Axon Framework or implement choreography via Kafka.

What is the purpose of the bootstrap context in Spring Cloud?

The bootstrap context loads configuration before the main application context, typically from a Spring Cloud Config Server. Bootstrap.yml is deprecated in Spring Cloud 2022+ in favor of standard config.

Originally published on Ayodhyyya. Last updated June 1, 2026.