Cloud Native 17 min read

Building a Microservice Architecture with Spring Cloud 2020 (Ilford) – Replacing Netflix Components

This article explains how to use the new Spring Cloud 2020 (Ilford) release to build a microservice architecture, covering the removal of Netflix Ribbon, Hystrix and Zuul, the introduction of Spring Cloud Load Balancer, Circuit Breaker, Config Server, and API Gateway, with full code examples and configuration details.

Top Architect
Top Architect
Top Architect
Building a Microservice Architecture with Spring Cloud 2020 (Ilford) – Replacing Netflix Components

Spring Cloud 2020.0.0 (Ilford) removed several Netflix components that were previously in maintenance mode, such as Ribbon, Hystrix, and Zuul, leaving only Eureka; the release introduces replacements like Spring Cloud Load Balancer, Spring Cloud Circuit Breaker (based on Resilience4J), and Spring Cloud Gateway.

The article guides readers through constructing a microservice system with the new components, including service discovery (Eureka or Consul), centralized configuration (Spring Cloud Config with Git or Vault back‑ends), inter‑service communication (RestTemplate, WebClient, OpenFeign), load balancing, and API gateway configuration.

1 Architecture

The sample architecture includes an API gateway, service discovery server, and configuration server, illustrating how to integrate Spring Cloud Gateway, Eureka/Consul, and Config Server.

2 Service Discovery

By adding a single starter dependency to the pom.xml, a microservice can switch between Eureka and Consul. Example for Eureka:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Example for Consul:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

Custom Eureka client configuration (e.g., dynamic ports) can be set in application.yml:

instance:
  instanceId: ${spring.cloud.client.hostname}:${spring.application.name}:${random.value}

Consul client configuration follows a similar structure.

To run a Consul server locally, Docker can be used:

$ docker run -d --name=consul -e CONSUL_BIND_INTERFACE=eth0 -p 8500:8500 consul:1.7.2

3 Distributed Configuration

Spring Cloud Config provides a centralized configuration server. The configuration can be stored in Git, Vault, or the file system. Example application.yml for a Config Server using native Git and Vault back‑ends:

spring:
  application:
    name: config-server
  profiles:
    active: native,vault
  cloud:
    config:
      server:
        native:
          searchLocations: classpath:/config-repo
        vault:
          host: 192.168.99.100
          authentication: TOKEN
          token: spring-microservices-course

When using discovery, the client enables the Config Server with bootstrap.yml and sets spring.cloud.config.discovery.enabled=true.

4 Service‑to‑Service Communication

Three HTTP‑based Spring components can be used: RestTemplate, WebClient, and OpenFeign. Load‑balanced beans are created with @LoadBalanced:

@Bean
@LoadBalanced
fun template(): RestTemplate = RestTemplateBuilder()
    .setReadTimeout(Duration.ofMillis(100))
    .setConnectTimeout(Duration.ofMillis(100))
    .build()

@Bean
@LoadBalanced
fun clientBuilder(): WebClient.Builder {
    val tcpClient = TcpClient.create()
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100)
        .doOnConnected { conn ->
            conn.addHandlerLast(ReadTimeoutHandler(100, TimeUnit.MILLISECONDS))
        }
    val connector = ReactorClientHttpConnector(HttpClient.from(tcpClient))
    return WebClient.builder().clientConnector(connector)
}

OpenFeign starter dependency:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

5 Circuit Breaker

Resilience4J based circuit breakers are added via spring-cloud-starter-circuitbreaker-resilience4j. A customizer bean configures sliding window size, failure rate threshold, and timeout:

@Bean
fun defaultCustomizer(): Customizer<Resilience4JCircuitBreakerFactory> {
    return Customizer { factory ->
        factory.configureDefault { id ->
            Resilience4JConfigBuilder(id)
                .timeLimiterConfig(TimeLimiterConfig.custom()
                    .timeoutDuration(Duration.ofMillis(500))
                    .build())
                .circuitBreakerConfig(CircuitBreakerConfig.custom()
                    .slidingWindowSize(10)
                    .failureRateThreshold(33.3F)
                    .slowCallRateThreshold(33.3F)
                    .build())
                .build()
        }
    }
}

Example controller using the circuit breaker:

@RestController
@RequestMapping("/caller")
class CallerController(private val template: RestTemplate, private val factory: Resilience4JCircuitBreakerFactory) {
    private var id: Int = 0

    @PostMapping("/random-send/{message}")
    fun randomSend(@PathVariable message: String): CallmeResponse? {
        val request = CallmeRequest(++id, message)
        val circuit = factory.create("random-circuit")
        return circuit.run { template.postForObject("http://inter-callme-service/callme/random-call", request, CallmeResponse::class.java) }
    }
}

6 Spring Cloud API Gateway

Spring Cloud Gateway replaces Zuul as the API gateway. The required dependencies include spring-cloud-starter-gateway, actuator, Kotlin reflect, and the Eureka client. Most routing and filter logic is defined in application.yml:

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      routes:
        - id: inter-callme-service
          uri: lb://inter-callme-service
          predicates:
            - Path=/api/callme/**
          filters:
            - RewritePath=/api(?/?.*), ${path}
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 20
                redis-rate-limiter.burstCapacity: 40
            - name: CircuitBreaker
              args:
                name: sampleSlowCircuitBreaker
                fallbackUri: forward:/fallback/test
        - id: inter-caller-service
          uri: lb://inter-caller-service
          predicates:
            - Path=/api/caller/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 20
                redis-rate-limiter.burstCapacity: 40
    loadbalancer:
      ribbon:
        enabled: false
  redis:
    host: 192.168.99.100
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always

Additional beans configure a KeyResolver for rate limiting and a reactive circuit‑breaker customizer.

7 Summary

The article demonstrates how to assemble a complete microservice solution with the latest Spring Cloud components, replacing deprecated Netflix libraries and leveraging Spring Cloud Load Balancer, Config Server, Service Discovery, Circuit Breaker, and API Gateway.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring Cloud
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.