Spring Cloud is a curated collection of battle-tested, production-ready frameworks—integrated and abstracted through Spring Boot’s convention-over-configuration model. It simplifies the development, deployment, and maintenance of distributed systems by encapsulating complexity behind intuitive APIs and declarative configurations.
Spring Cloud vs. Dubbo
Both Spring Cloud and Apache Dubbo support microservice architectures, but differ fundamentally in scope and communication style. Dubbo focuses narrowly on service governance (e.g., reigstration, discovery, load balancing) using high-performence RPC over protocols like Dubbo or gRPC. In contrast, Spring Cloud offers a comprehensive ecosystem—including configuration management, circuit breaking, API gateways, and distributed tracing—built around HTTP/RESTful semantics. While Dubbo may yield lower latency in tightly coupled internal networks, Spring Cloud prioritizes interoperability, tooling maturity, and cloud-native alignment.
Setting Up an Eureka Server
To deploy a standalone Eureka registry server, declare the Spring Cloud BOM and include the Netflix Eureka server starter:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<spring-cloud.version>2021.0.8</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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
Configure the server to disable self-registration and registry fetching (since it's the central registry):
server:
port: 8761
eureka:
instance:
hostname: registry
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
wait-time-in-ms-when-sync-empty: 0
Enable Eureka server behavior with @EnableEurekaServer on the main application class.
Registering Eureka Clients
Service providers and consumers must include the Eureka client starter:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
A typical provider configuration:
server:
port: 8082
spring:
application:
name: inventory-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: ${spring.application.name}:${random.int[1000,9999]}
A consumer config differs only in application name and port:
server:
port: 8083
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
Both services automatically register at startup when annotated with @EnableEurekaClient (or implicitly via auto-configuration in newer versions).
Declarative HTTP Clients with OpenFeign
OpenFeign provides compile-time interface-based REST clients. Define a typed contract matching the target service’s endpoints:
@FeignClient(name = "inventory-service")
public interface InventoryClient {
@GetMapping("/api/items/{itemId}")
Item retrieveItem(@PathVariable("itemId") Long itemId);
}
Inject and use it like any Spring bean:
@Service
public class OrderProcessingService {
private final InventoryClient inventoryClient;
public OrderProcessingService(InventoryClient inventoryClient) {
this.inventoryClient = inventoryClient;
}
public void placeOrder(Long itemId) {
Item item = inventoryClient.retrieveItem(itemId);
// process order...
}
}
Tune timeouts globally via Ribbon (legacy) or LoadBalancer (modern) properties:
spring:
cloud:
loadbalancer:
configs:
default:
retry:
enabled: true
max-retries-on-same-service-instance: 1
max-retries-on-next-service-instance: 1
feign:
client:
config:
default:
connectTimeout: 2000
readTimeout: 5000
Enable detailed Feign logging by configuring the log level:
logging:
level:
com.example.clients.InventoryClient: DEBUG
Optionallly define a custom logger configuration bean:
@Configuration
public class FeignLoggingConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}