Spring Cloud provides tools for building distributed systems and microservices. It builds on Spring Boot to add patterns like service discovery, configuration management, API gateway, and circuit breaking.
| Component | Purpose | Technology |
|---|---|---|
| Service Discovery | Services register and find each other by name | Eureka, Consul |
| API Gateway | Single entry point for all client requests | Spring Cloud Gateway |
| Config Server | Centralized external configuration | Spring Cloud Config |
| Load Balancing | Distribute requests across service instances | Spring Cloud LoadBalancer |
| Circuit Breaker | Prevent cascading failures | Resilience4j |
| Feign Client | Declarative HTTP client for inter-service calls | OpenFeign |
// Eureka Server - Service Registry
// pom.xml dependency: spring-cloud-starter-netflix-eureka-server
package com.example.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // Enables the Eureka service registry
public class EurekaServerApp {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApp.class, args);
}
}
// application.yml for Eureka Server:
// server:
// port: 8761
// eureka:
// client:
// register-with-eureka: false # Server doesn't register itself
// fetch-registry: false
// Eureka Client - Microservice that registers with Eureka
// pom.xml dependency: spring-cloud-starter-netflix-eureka-client
package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // Registers this service with Eureka
public class UserServiceApp {
public static void main(String[] args) {
SpringApplication.run(UserServiceApp.class, args);
}
}
# application.yml for User Service (Eureka Client)
spring:
application:
name: user-service # Service name used for discovery
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
// pom.xml: spring-cloud-starter-openfeign
// Main class: @EnableFeignClients
package com.example.orderservice.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
// name = Eureka service name of the target microservice
@FeignClient(name = "user-service", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
@GetMapping("/api/users/{id}")
UserDto getUserById(@PathVariable("id") Long id);
@GetMapping("/api/users")
List<UserDto> getAllUsers();
}
// Fallback class for circuit breaker (Resilience4j)
@Component
class UserFeignClientFallback implements UserFeignClient {
@Override
public UserDto getUserById(Long id) {
return new UserDto(id, "Unknown", "N/A"); // Default response on failure
}
@Override
public List<UserDto> getAllUsers() {
return Collections.emptyList();
}
}
package com.example.orderservice.service;
import com.example.orderservice.client.UserFeignClient;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final UserFeignClient userFeignClient;
private final OrderRepository orderRepository;
public OrderService(UserFeignClient userFeignClient,
OrderRepository orderRepository) {
this.userFeignClient = userFeignClient;
this.orderRepository = orderRepository;
}
public OrderDto createOrder(Long userId, Long productId, int qty) {
// Call user-service via Feign (load-balanced automatically)
UserDto user = userFeignClient.getUserById(userId);
if (user == null) throw new RuntimeException("User not found: " + userId);
Order order = new Order(userId, productId, qty);
Order saved = orderRepository.save(order);
return new OrderDto(saved, user);
}
}
# Spring Cloud Gateway - routes all client traffic to microservices
# pom.xml: spring-cloud-starter-gateway
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
# Route to user-service (resolved via Eureka)
- id: user-service-route
uri: lb://user-service # lb:// = load-balanced via Eureka
predicates:
- Path=/api/users/**
filters:
- StripPrefix=0
- AddRequestHeader=X-Gateway, true
# Route to order-service
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/orders/**
# Route with rate limiting
- id: product-service-route
uri: lb://product-service
predicates:
- Path=/api/products/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
server:
port: 8080
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
Explore 500+ free tutorials across 20+ languages and frameworks.