Spring Cloud

Complete guide to Spring Cloud: the Spring framework for building microservices and cloud-native applications. Learn service discovery, API gateway, configuration management, circuit breakers, and distributed systems patterns.

Table of Contents

1. What is Spring Cloud?

Spring Cloud is a collection of frameworks and tools for building cloud-native applications and microservices architectures. It provides solutions for common patterns in distributed systems, such as configuration management, service discovery, circuit breakers, API gateways, and distributed tracing.

Spring Cloud builds on top of Spring Boot, leveraging its auto-configuration and convention-over-configuration philosophy to simplify the development of distributed systems. It provides a consistent programming model for building microservices that can run in any environment, from local development to cloud platforms.

The framework addresses the challenges of building distributed systems, including:

  • Service discovery and registration
  • Distributed configuration management
  • API gateway and routing
  • Circuit breakers and fault tolerance
  • Load balancing
  • Distributed tracing and monitoring
  • Service-to-service communication

2. Why Use Spring Cloud?

  • Microservices Support: Complete toolkit for building microservices architectures.
  • Spring Boot Integration: Seamless integration with Spring Boot's auto-configuration.
  • Cloud-Native: Designed for cloud platforms like Kubernetes, Cloud Foundry, and AWS.
  • Production-Ready: Battle-tested components used in production environments.
  • Flexible: Mix and match components based on your needs.
  • Standards-Based: Implements industry-standard patterns and protocols.
  • Developer-Friendly: Reduces boilerplate code and simplifies distributed system development.
  • Ecosystem: Large ecosystem of Spring Cloud modules and integrations.

3. Spring Cloud Architecture

Spring Cloud follows a microservices architecture pattern where services are independently deployable, loosely coupled, and communicate over well-defined APIs:

3.1 Architecture Layers

  1. Client Layer: Web applications, mobile apps, or external systems.
  2. API Gateway Layer: Single entry point for all client requests.
  3. Service Layer: Microservices implementing business logic.
  4. Infrastructure Layer: Service discovery, configuration, monitoring, and tracing.

This architecture provides:

  • Scalability through independent service scaling
  • Resilience through circuit breakers and retry mechanisms
  • Observability through distributed tracing and monitoring
  • Flexibility through service discovery and dynamic configuration
graph TB subgraph "Client Layer" A[Web Client] B[Mobile App] C[External System] end subgraph "API Gateway Layer" D[Spring Cloud Gateway] E[Load Balancer] F[Rate Limiter] end subgraph "Service Discovery" G[Eureka Server] H[Consul] end subgraph "Configuration" I[Config Server] J[Git Repository] end subgraph "Service Layer" K[User Service] L[Order Service] M[Payment Service] N[Notification Service] end subgraph "Infrastructure" O[Circuit Breaker] P[Distributed Tracing] Q[Monitoring] end A --> D B --> D C --> D D --> E E --> F F --> K F --> L F --> M F --> N K --> G L --> G M --> G N --> G K --> I L --> I M --> I N --> I I --> J K --> O L --> O M --> O K --> P L --> P M --> P N --> P P --> Q style A fill:#e1f5ff,stroke:#0273bd,stroke-width:3px style D fill:#fff4e1,stroke:#f57c00,stroke-width:2px style G fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px style I fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px style K fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style L fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style M fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style N fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px

4. Core Components

4.1 Service Discovery

Service Discovery allows services to find and communicate with each other without hard-coded endpoints. Services register themselves with a discovery server and can discover other services by name.

Spring Cloud supports multiple service discovery implementations:

  • Netflix Eureka: REST-based service registry
  • Consul: Service discovery and configuration
  • Zookeeper: Distributed coordination service
  • Kubernetes: Native Kubernetes service discovery

4.2 API Gateway

API Gateway provides a single entry point for all client requests, handling routing, load balancing, authentication, rate limiting, and cross-cutting concerns.

Spring Cloud Gateway is a reactive, non-blocking API gateway built on Spring WebFlux.

4.3 Configuration Server

Configuration Server centralizes configuration management, allowing you to store configuration in Git, SVN, or other repositories and distribute it to microservices.

Spring Cloud Config provides server-side and client-side support for externalized configuration.

4.4 Circuit Breaker

Circuit Breaker prevents cascading failures by stopping requests to failing services and providing fallback mechanisms.

Spring Cloud supports Resilience4j and Netflix Hystrix (deprecated) for circuit breaker patterns.

4.5 Load Balancer

Load Balancer distributes requests across multiple service instances to improve performance and availability.

Spring Cloud LoadBalancer provides client-side load balancing for Spring applications.

4.6 Distributed Tracing

Distributed Tracing tracks requests as they flow through multiple microservices, providing visibility into system behavior and performance.

Spring Cloud Sleuth integrates with tracing systems like Zipkin and Jaeger.

5. Service Discovery in Detail

5.1 Eureka Server

Eureka Server is a service registry where services register themselves and discover other services.

// Eureka Server Application
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

// application.yml
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

5.2 Eureka Client

Eureka Client registers services with Eureka Server and discovers other services.

// Service Application
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// application.yml
spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 30
    lease-expiration-duration-in-seconds: 90

5.3 Service Discovery with RestTemplate

Using service discovery to call other services:

@Service
public class OrderService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    public User getUser(Long userId) {
        // Get service instances
        List<ServiceInstance> instances = 
            discoveryClient.getInstances("user-service");
        
        if (instances.isEmpty()) {
            throw new RuntimeException("User service not available");
        }
        
        // Use first available instance
        ServiceInstance instance = instances.get(0);
        String url = "http://" + instance.getHost() + ":" + 
                     instance.getPort() + "/api/users/" + userId;
        
        return restTemplate.getForObject(url, User.class);
    }
}

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

5.4 Service Discovery with Feign Client

Feign provides a declarative way to make HTTP calls to other services:

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

@FeignClient(name = "user-service")
public interface UserServiceClient {
    
    @GetMapping("/api/users/{id}")
    User getUser(@PathVariable Long id);
    
    @GetMapping("/api/users")
    List<User> getAllUsers();
    
    @PostMapping("/api/users")
    User createUser(@RequestBody User user);
}

@Service
public class OrderService {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    public Order createOrder(OrderRequest request) {
        User user = userServiceClient.getUser(request.getUserId());
        // Process order
        return order;
    }
}

5.5 Consul Service Discovery

Using Consul as an alternative to Eureka:

// application.yml
spring:
  application:
    name: user-service
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        enabled: true
        service-name: ${spring.application.name}
        health-check-path: /actuator/health
        health-check-interval: 10s

// Enable Consul Discovery
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

6. API Gateway in Detail

6.1 Spring Cloud Gateway Setup

Spring Cloud Gateway provides routing, filtering, and cross-cutting concerns for microservices.

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

// application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
            
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
            
        - id: payment-service
          uri: lb://payment-service
          predicates:
            - Path=/api/payments/**
          filters:
            - StripPrefix=1
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

6.2 Custom Filters

Creating custom gateway filters for authentication, logging, and transformation:

@Component
public class AuthenticationFilter implements GatewayFilter, Ordered {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, 
                              GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // Check for authentication token
        String token = request.getHeaders().getFirst("Authorization");
        
        if (token == null || !isValidToken(token)) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        
        // Add user info to headers
        ServerHttpRequest modifiedRequest = request.mutate()
            .header("X-User-Id", extractUserId(token))
            .build();
        
        return chain.filter(exchange.mutate()
            .request(modifiedRequest)
            .build());
    }
    
    @Override
    public int getOrder() {
        return -100;
    }
    
    private boolean isValidToken(String token) {
        // Token validation logic
        return true;
    }
    
    private String extractUserId(String token) {
        // Extract user ID from token
        return "user123";
    }
}

// Using custom filter
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - name: AuthenticationFilter
            - StripPrefix=1

6.3 Rate Limiting

Implementing rate limiting with Redis:

// Add dependency
// <dependency>
//     <groupId>com.github.vladimir-bukhtoyarov</groupId>
//     <artifactId>bucket4j-spring-boot-starter</artifactId>
// </dependency>

@Configuration
public class RateLimitingConfig {
    
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> {
            String userId = exchange.getRequest()
                .getHeaders()
                .getFirst("X-User-Id");
            return Mono.just(userId != null ? userId : "anonymous");
        };
    }
}

// application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
                redis-rate-limiter.requestedTokens: 1
                key-resolver: "#{@userKeyResolver}"

6.4 Circuit Breaker in Gateway

Adding circuit breaker to gateway routes:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - name: CircuitBreaker
              args:
                name: userServiceCircuitBreaker
                fallbackUri: forward:/fallback/user-service

7. Configuration Server in Detail

7.1 Config Server Setup

Setting up Spring Cloud Config Server to centralize configuration:

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

// application.yml (Config Server)
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-org/config-repo
          search-paths: '{application}'
          clone-on-start: true
          force-pull: true

7.2 Config Client Setup

Configuring microservices to use Config Server:

// bootstrap.yml (Config Client)
spring:
  application:
    name: user-service
  cloud:
    config:
      uri: http://localhost:8888
      fail-fast: true
      retry:
        initial-interval: 1000
        max-attempts: 6
        max-interval: 2000
        multiplier: 1.1

// application.yml (local overrides)
server:
  port: 8081

// Config files in Git repository:
// user-service.yml
server:
  port: 8081

database:
  url: jdbc:postgresql://localhost:5432/users
  username: user
  password: password

// user-service-dev.yml (profile-specific)
database:
  url: jdbc:postgresql://dev-db:5432/users
  username: dev_user
  password: dev_password

// user-service-prod.yml
database:
  url: jdbc:postgresql://prod-db:5432/users
  username: prod_user
  password: ${DB_PASSWORD}

7.3 Dynamic Configuration Refresh

Refreshing configuration without restarting services:

// Add dependency
// <dependency>
//     <groupId>org.springframework.boot</groupId>
//     <artifactId>spring-boot-starter-actuator</artifactId>
// </dependency>

// Enable refresh endpoint
management:
  endpoints:
    web:
      exposure:
        include: refresh, health, info

// Refreshable configuration
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "database")
public class DatabaseConfig {
    private String url;
    private String username;
    private String password;
    
    // Getters and setters
}

// Refresh configuration via HTTP POST
// POST http://localhost:8081/actuator/refresh

7.4 Config Server with Vault

Using HashiCorp Vault for secure configuration storage:

// Config Server with Vault backend
spring:
  cloud:
    config:
      server:
        vault:
          host: localhost
          port: 8200
          scheme: http
          authentication: TOKEN
          token: your-vault-token

// Config Client
spring:
  cloud:
    config:
      uri: http://localhost:8888
      vault:
        enabled: true

8. Circuit Breaker in Detail

8.1 Resilience4j Setup

Using Resilience4j for circuit breaker, retry, and rate limiting:

// Dependencies
// <dependency>
//     <groupId>io.github.resilience4j</groupId>
//     <artifactId>resilience4j-spring-boot2</artifactId>
// </dependency>
// <dependency>
//     <groupId>io.github.resilience4j</groupId>
//     <artifactId>resilience4j-reactor</artifactId>
// </dependency>

@Service
public class OrderService {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @CircuitBreaker(name = "userService", fallbackMethod = "getUserFallback")
    @Retry(name = "userService")
    @RateLimiter(name = "userService")
    public User getUser(Long userId) {
        return userServiceClient.getUser(userId);
    }
    
    public User getUserFallback(Long userId, Exception e) {
        // Fallback logic
        return new User(userId, "Default User");
    }
}

// application.yml
resilience4j:
  circuitbreaker:
    instances:
      userService:
        registerHealthIndicator: true
        slidingWindowSize: 10
        minimumNumberOfCalls: 5
        permittedNumberOfCallsInHalfOpenState: 3
        automaticTransitionFromOpenToHalfOpenEnabled: true
        waitDurationInOpenState: 10s
        failureRateThreshold: 50
        eventConsumerBufferSize: 10
  retry:
    instances:
      userService:
        maxAttempts: 3
        waitDuration: 1000
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
  ratelimiter:
    instances:
      userService:
        limitForPeriod: 10
        limitRefreshPeriod: 1s
        timeoutDuration: 0

8.2 Circuit Breaker with Feign

Integrating circuit breaker with Feign clients:

@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
    
    @GetMapping("/api/users/{id}")
    User getUser(@PathVariable Long id);
}

@Component
public class UserServiceFallback implements UserServiceClient {
    
    @Override
    public User getUser(Long id) {
        return new User(id, "Fallback User");
    }
}

// Enable circuit breaker for Feign
feign:
  circuitbreaker:
    enabled: true

8.3 Bulkhead Pattern

Implementing bulkhead pattern to isolate resources:

@Service
public class OrderService {
    
    @Bulkhead(name = "orderProcessing", type = BulkheadType.THREADPOOL)
    public CompletableFuture<Order> processOrder(Order order) {
        // Process order in isolated thread pool
        return CompletableFuture.supplyAsync(() -> {
            // Order processing logic
            return order;
        });
    }
}

// application.yml
resilience4j:
  bulkhead:
    instances:
      orderProcessing:
        maxConcurrentCalls: 10
        maxWaitDuration: 0

9. Project Setup

9.1 Maven Dependencies

<properties>
    <spring-cloud.version>2023.0.0</spring-cloud.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- Spring Cloud Starter -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter</artifactId>
    </dependency>
    
    <!-- Service Discovery -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <!-- API Gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
    <!-- Config Server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    
    <!-- Config Client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
    <!-- Circuit Breaker -->
    <dependency>
        <groupId>io.github.resilience4j</groupId>
        <artifactId>resilience4j-spring-boot3</artifactId>
    </dependency>
    
    <!-- Load Balancer -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    
    <!-- Distributed Tracing -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
    <dependency>
        <groupId>io.zipkin.reporter2</groupId>
        <artifactId>zipkin-reporter-brave</artifactId>
    </dependency>
</dependencies>

9.2 Spring Boot Parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath/>
</parent>

10. Real-World Examples

10.1 Complete Microservices Architecture

A complete example with multiple microservices, API gateway, service discovery, and configuration:

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

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

// API Gateway
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}

// User Service
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// Order Service
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

// Order Service calling User Service
@Service
public class OrderService {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @CircuitBreaker(name = "userService", fallbackMethod = "createOrderFallback")
    public Order createOrder(OrderRequest request) {
        User user = userServiceClient.getUser(request.getUserId());
        
        Order order = new Order();
        order.setUserId(user.getId());
        order.setItems(request.getItems());
        order.setTotal(calculateTotal(request.getItems()));
        
        return orderRepository.save(order);
    }
    
    private Order createOrderFallback(OrderRequest request, Exception e) {
        // Fallback: create order without user validation
        Order order = new Order();
        order.setUserId(request.getUserId());
        order.setItems(request.getItems());
        order.setTotal(calculateTotal(request.getItems()));
        order.setStatus("PENDING_VALIDATION");
        
        return orderRepository.save(order);
    }
}

10.2 Distributed Tracing Example

Setting up distributed tracing across microservices:

// application.yml
spring:
  sleuth:
    zipkin:
      base-url: http://localhost:9411
    sampler:
      probability: 1.0

// Service automatically traces HTTP calls
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        // Trace automatically added
        return orderService.getOrder(id);
    }
    
    @PostMapping
    public Order createOrder(@RequestBody OrderRequest request) {
        // Trace spans across services
        return orderService.createOrder(request);
    }
}

11. Best Practices

  • Service Independence: Each microservice should be independently deployable and scalable.
  • API Versioning: Version your APIs to support backward compatibility.
  • Configuration Management: Use Config Server for centralized configuration management.
  • Circuit Breakers: Implement circuit breakers to prevent cascading failures.
  • Distributed Tracing: Use distributed tracing for observability and debugging.
  • Health Checks: Implement health checks for service discovery and monitoring.
  • Security: Implement authentication and authorization at the API gateway level.
  • Monitoring: Monitor service metrics, logs, and traces.
  • Error Handling: Implement proper error handling and fallback mechanisms.
  • Testing: Test services in isolation and integration.

12. Testing

Testing microservices with Spring Cloud:

@SpringBootTest
@AutoConfigureMockMvc
public class OrderServiceTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserServiceClient userServiceClient;
    
    @Test
    public void testCreateOrder() {
        User user = new User(1L, "John Doe");
        when(userServiceClient.getUser(1L)).thenReturn(user);
        
        OrderRequest request = new OrderRequest();
        request.setUserId(1L);
        request.setItems(Arrays.asList(new OrderItem()));
        
        mockMvc.perform(post("/api/orders")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(request)))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.userId").value(1L));
    }
    
    @Test
    public void testCircuitBreaker() {
        when(userServiceClient.getUser(anyLong()))
            .thenThrow(new RuntimeException("Service unavailable"));
        
        OrderRequest request = new OrderRequest();
        request.setUserId(1L);
        
        // Should use fallback
        mockMvc.perform(post("/api/orders")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(request)))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.status").value("PENDING_VALIDATION"));
    }
}

13. Advanced Concepts

13.1 Service Mesh Integration

Integrating Spring Cloud with service mesh solutions like Istio:

// Kubernetes deployment with Istio
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
      annotations:
        sidecar.istio.io/inject: "true"
    spec:
      containers:
      - name: user-service
        image: user-service:latest
        ports:
        - containerPort: 8080

13.2 Event-Driven Architecture

Using Spring Cloud Stream for event-driven microservices:

// Publisher
@Service
public class OrderEventPublisher {
    
    @Autowired
    private StreamBridge streamBridge;
    
    public void publishOrderCreated(Order order) {
        streamBridge.send("orderCreated-out-0", order);
    }
}

// Consumer
@Configuration
public class OrderEventConsumer {
    
    @Bean
    public Consumer<Order> orderCreated() {
        return order -> {
            // Process order created event
            System.out.println("Order created: " + order.getId());
        };
    }
}

// application.yml
spring:
  cloud:
    stream:
      bindings:
        orderCreated-out-0:
          destination: orders
        orderCreated-in-0:
          destination: orders
          group: order-processor

13.3 Kubernetes Native

Using Spring Cloud Kubernetes for Kubernetes-native service discovery:

// Dependencies
// <dependency>
//     <groupId>org.springframework.cloud</groupId>
//     <artifactId>spring-cloud-starter-kubernetes-client-discovery</artifactId>
// </dependency>

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

// application.yml
spring:
  cloud:
    kubernetes:
      discovery:
        enabled: true
        namespaces:
          - default
          - production

14. Conclusion

Spring Cloud provides a comprehensive toolkit for building microservices and cloud-native applications. It addresses the common challenges of distributed systems through proven patterns and Spring's familiar programming model.

Key takeaways:

  • Spring Cloud simplifies microservices development
  • It provides solutions for service discovery, configuration, and resilience
  • Components work together seamlessly
  • Supports multiple deployment environments
  • Follows Spring Boot's convention-over-configuration philosophy

Whether you're building microservices from scratch or migrating a monolith, Spring Cloud provides the tools and patterns you need to build robust, scalable, and maintainable distributed systems.

Post a Comment

0 Comments