Components Map

The Big Picture

React / Android
                               |
                               v
                  +-------------------------+        +----------------------+
                  |  Spring Cloud Gateway   | -----> |  Config Server       |
                  |  routes, auth, limits   |        |  (Git-backed YAML)   |
                  +------------+------------+        +----------+-----------+
                               |  lb://order-service             ^
                               v                                 | config at startup
   +----------------+   +----------------+   +----------------+  |
   | product-service|<--| order-service  |-->| payment-service|--+
   +-------+--------+   +-------+--------+   +--------+-------+
           |   OpenFeign + LoadBalancer + Resilience4j |
           |                    |                      |
           +--------- register / look up --------------+
                                |
                     +----------v----------+        +-------------------+
                     |   Eureka Server     |        |  Kafka (Stream)   |
                     |  service registry   |        |  OrderPlaced ...  |
                     +---------------------+        +-------------------+

   Tracing: Micrometer Tracing -> Zipkin   (spans across every service)

Component Reference

ComponentStarter (artifactId)What it doesCovered in
Eureka Server / Clientspring-cloud-starter-netflix-eureka-server / -clientService registry; services register and find each other by nameMedium
Spring Cloud LoadBalancerspring-cloud-starter-loadbalancerClient-side load balancing across instances (lb://)Medium
Spring Cloud Gatewayspring-cloud-starter-gateway (WebFlux) or -gateway-mvcAPI gateway: routes, filters, rate limiting, authMedium
Spring Cloud Configspring-cloud-config-server / spring-cloud-starter-configCentral configuration from Git, with refreshMedium
Spring Cloud OpenFeignspring-cloud-starter-openfeignDeclarative REST clients from interfacesMedium
Circuit Breaker (Resilience4j)spring-cloud-starter-circuitbreaker-resilience4jCircuit breaker, retry, rate limiter, bulkheadMedium
Spring Cloud Streamspring-cloud-stream-binder-kafka / -rabbitEvent-driven messaging with Kafka/RabbitMQMedium
Micrometer Tracing (Boot)micrometer-tracing-bridge-brave + zipkin-reporter-braveDistributed tracing (replaced Spring Cloud Sleuth)Advance
Spring Cloud Kubernetesspring-cloud-starter-kubernetes-clientUse Kubernetes Services and ConfigMaps from SpringAdvance

Retired Netflix Components

Old (do not use in new code)Replacement today
Netflix Ribbon (client load balancing)Spring Cloud LoadBalancer
Netflix Hystrix (circuit breaker)Resilience4j via Spring Cloud Circuit Breaker
Netflix Zuul 1 (gateway)Spring Cloud Gateway
Spring Cloud Sleuth (tracing)Micrometer Tracing (built into Spring Boot 3)

Tip: Old blog posts and YouTube videos still show Ribbon, Hystrix, Zuul and Sleuth. If you see them, the tutorial is from the Spring Boot 2 era. Eureka is the one Netflix component that is still actively supported.

Example: What a Service Registry Does

Example

A preview of service discovery (built for real with Eureka at the medium level): services register by name, and a caller asks for "product-service" instead of a fixed URL and gets instances in round-robin order:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        ServiceRegistry registry = new ServiceRegistry();
        registry.register("product-service", "http://10.0.0.5:8081");
        registry.register("product-service", "http://10.0.0.6:8081");
        registry.register("order-service", "http://10.0.0.7:8082");

        System.out.println("Registry: " + registry.all());
        for (int i = 1; i <= 4; i++) {
            System.out.println("Call " + i + " -> " + registry.choose("product-service") + "/api/products/1");
        }

        registry.deregister("product-service", "http://10.0.0.5:8081"); // instance crashed
        System.out.println("After one instance went down:");
        System.out.println("Call 5 -> " + registry.choose("product-service") + "/api/products/1");
    }
}

class ServiceRegistry {
    private final Map<String, List<String>> instances = new TreeMap<>();
    private final Map<String, Integer> next = new HashMap<>();

    void register(String name, String url) {
        instances.computeIfAbsent(name, k -> new ArrayList<>()).add(url);
    }
    void deregister(String name, String url) { instances.get(name).remove(url); }

    String choose(String name) {           // round-robin load balancing
        List<String> list = instances.getOrDefault(name, List.of());
        if (list.isEmpty()) throw new IllegalStateException("No instances of " + name);
        int i = next.merge(name, 1, Integer::sum) - 1;
        return list.get(i % list.size());
    }
    Map<String, List<String>> all() { return instances; }
}

Output

Registry: {order-service=[http://10.0.0.7:8082], product-service=[http://10.0.0.5:8081, http://10.0.0.6:8081]}
Call 1 -> http://10.0.0.5:8081/api/products/1
Call 2 -> http://10.0.0.6:8081/api/products/1
Call 3 -> http://10.0.0.5:8081/api/products/1
Call 4 -> http://10.0.0.6:8081/api/products/1
After one instance went down:
Call 5 -> http://10.0.0.6:8081/api/products/1