Discovery & Gateway — Cheat Sheet
Microservices · 4 topics. Download the PDF or the Instagram carousel and share it.
Service Discovery — Eureka
Service instances register with a registry (Eureka, Consul) on startup; clients query the registry or use client-side load balancing (Ribbon/Spring Cloud LoadBalancer) to resolve addresses.
- ✓Client-side discovery (Eureka + LoadBalancer): client fetches registry and picks instance. Server-side discovery (K8s Service, ALB): proxy picks instance.
- ✓Eureka heartbeat: 30 s; eviction timeout: 90 s — newly registered instances can take up to 60 s to become visible to all clients.
- ✓Spring Cloud LoadBalancer replaces the deprecated Ribbon; use @LoadBalanced WebClient or OpenFeign with lb:// URIs.
- ✓In Kubernetes, kube-dns provides built-in service discovery via ClusterIP Services — no Eureka server needed.
- ✓Spring Cloud Kubernetes integrates with the K8s API server for service discovery in cloud-native deployments.
- ✓Always configure health checks (Actuator /health) so the registry removes unhealthy instances before they receive traffic.
<!-- Eureka Server — standalone registry -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServer { }
# application.yml — Eureka Server
server.port: 8761
eureka:
client:
register-with-eureka: false # the server doesn't register itself
fetch-registry: false
---
<!-- Eureka Client — every microservice -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
# application.yml — Microservice
spring.application.name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
prefer-ip-address: true # register with IP, not hostname
lease-renewal-interval-in-seconds: 30
lease-expiration-duration-in-seconds: 90API Gateway Pattern
A single entry point that handles routing, authentication, rate limiting, SSL termination, and request/response transformation, shielding clients from internal topology.
- ✓The API Gateway is the single entry point for all external traffic — it shields clients from the internal microservices topology.
- ✓Centralise cross-cutting concerns at the gateway: JWT validation, rate limiting, SSL termination, request logging, and CORS.
- ✓Downstream services trust identity headers (X-User-Id, X-User-Role) forwarded by the gateway — they don't need their own auth logic.
- ✓Spring Cloud Gateway uses Netty and Project Reactor — it is fully reactive and non-blocking, suitable for high-concurrency traffic.
- ✓The gateway should be stateless and horizontally scalable — use Redis for distributed rate limiting and token blacklisting.
- ✓A gateway introduces a single point of failure — deploy multiple instances behind a load balancer with health checks.
# Spring Cloud Gateway — application.yml route configuration
spring:
cloud:
gateway:
routes:
# Route 1: forward /api/orders/** → order-service
- id: order-service
uri: lb://order-service # lb:// = load-balanced via Eureka
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1 # strip /api before forwarding
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 10 req/sec
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userKeyResolver}"
# Route 2: forward /api/users/** → user-service
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- AddRequestHeader=X-Gateway-Source, api-gatewaySpring Cloud Gateway
Spring Cloud Gateway is a reactive API gateway built on Project Reactor; predicates match routes and filters (add headers, retry, rate-limit) process requests and responses.
- ✓Spring Cloud Gateway is non-blocking (WebFlux/Reactor) — handles high concurrency with few threads
- ✓Routes: uri + predicates (match) + filters (transform) — evaluated by order field ascending
- ✓StripPrefix removes path segments before forwarding; RewritePath transforms with regex
- ✓RequestRateLimiter filter uses Redis token bucket — throttles per user/IP key
- ✓GlobalFilter applies to ALL routes — use for authentication, request ID injection, logging
- ✓CircuitBreaker filter wraps each upstream call with Resilience4j; fallbackUri handles failures
# application.yml
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service # lb:// → Spring Cloud LoadBalancer
predicates:
- Path=/api/orders/**
- Method=GET,POST
filters:
- StripPrefix=1 # /api/orders/123 → /orders/123
- AddRequestHeader=X-Gateway-Source, gateway
- name: CircuitBreaker
args:
name: order-service
fallbackUri: forward:/fallback/orders
- id: auth-service
uri: lb://auth-service
predicates:
- Path=/api/auth/**
filters:
- RewritePath=/api/auth/(?<segment>.*), /${segment}
# Default route — catch-all fallback
- id: monolith-fallback
uri: http://monolith:8080
predicates: [Path=/**]
order: 9999Client-Side Load Balancing
Spring Cloud LoadBalancer selects a service instance from the registry using round-robin or custom strategies, allowing callers to balance traffic without a dedicated proxy.
- ✓Client-side LB fetches instances from the registry and selects one before calling.
- ✓@LoadBalanced on RestTemplate or WebClient.Builder enables SCL automatically.
- ✓Use the logical service name (http://service-id/...) — SCL resolves it to a real address.
- ✓Spring Cloud LoadBalancer replaced Netflix Ribbon in Spring Cloud 2020+.
- ✓Default strategy is round-robin; swap with a custom ReactorServiceInstanceLoadBalancer.
- ✓@LoadBalancerClient scopes a custom strategy to a specific target service.
// Configuration
@Configuration
public class WebConfig {
@Bean
@LoadBalanced // enables client-side LB on this RestTemplate
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
// Usage — use logical service name, not a real host
@Service
public class OrderClient {
private final RestTemplate restTemplate;
public ProductDTO getProduct(Long id) {
// "product-service" is the service ID in Eureka/Consul
return restTemplate.getForObject(
"http://product-service/api/products/{id}",
ProductDTO.class, id);
// SCL resolves → e.g. http://10.0.1.15:8081/api/products/42
}
}