Spring Cloud Interview Questions
Commonly asked Spring Cloud interview questions with clear, practical answers.
A curated set of Spring Cloud interview questions, tying each component back to the distributed-systems problem it solves.
Q: What problem does service discovery solve, and why can't services just call each other by a fixed hostname/IP?
In a system where instances are frequently started, stopped, scaled, and rescheduled (especially under an orchestrator like Kubernetes), a specific instance's address is only valid until the next reschedule — hardcoding it breaks the moment that happens. Service discovery (Eureka, Consul) solves this by having every instance register itself with a shared registry on startup, so a caller asks the registry "give me a healthy instance of orders-service" by logical name instead of relying on a fixed address, and gets back whichever instance is currently available.
Q: What benefits does a centralized Config Server provide over each service keeping its own configuration?
Without it, shared settings (database URLs, feature flags, third-party credentials) are duplicated across every service's own configuration files, so a change means editing and redeploying each service individually. Spring Cloud Config Server centralizes configuration in one place — typically backed by Git, so changes are version-controlled — and services simply fetch their configuration from it at startup, matched by application name and active profile. This turns a config change into an update to one shared source instead of a coordinated multi-service redeploy.
Q: How does the circuit breaker pattern work in Spring Cloud, and what does Resilience4j's @CircuitBreaker actually do?
A circuit breaker wraps a call to a potentially unreliable dependency and tracks its recent failure rate. While failures stay below a configured threshold, it stays closed and calls pass through normally. Once the failure rate crosses that threshold, it trips open — further calls fail immediately (running a designated fallback instead) without even attempting the network call, for a configured cooldown period — preventing a struggling downstream service from being hit with more load, and preventing the caller from piling up its own resources waiting on doomed calls. After the cooldown, it moves to half-open, allowing a few test calls through; if those succeed, it closes again and normal traffic resumes.
Q: Why combine @Retry with @CircuitBreaker instead of using either alone?
@Retry alone handles brief, transient failures well (a single dropped connection) but, applied to a genuinely struggling service, can make things worse — every caller retrying independently piles additional load onto an already-overwhelmed dependency, a "retry storm." @CircuitBreaker alone handles sustained failure well but doesn't help with brief blips that would have succeeded on a second attempt. Combined, retries absorb short-lived hiccups while the circuit breaker detects sustained failure and stops sending traffic entirely until the dependency has had a chance to recover.
Q: What role does Spring Cloud Gateway play in a microservices architecture?
It acts as a single entry point for external traffic, routing each incoming request to the correct internal service based on path (or other) predicates, typically resolving the target service dynamically through service discovery rather than fixed addresses. Centralizing routing here also gives a natural place to apply cross-cutting concerns — authentication, rate limiting, request logging, header manipulation — once, at the edge, instead of every downstream service having to implement the same concerns independently.
Q: What is a trace ID, and how does distributed tracing help debug a request that spans multiple services?
A trace ID is a shared identifier attached to a request the moment it enters the system and propagated automatically through every subsequent internal service-to-service call, so each service's own reported span (its portion of handling that request) can be correlated back to the same original request. Without it, each service's logs only show its own isolated piece of the story, with no way to tell which log lines across different services belong to the same user-facing request. A tool like Zipkin then renders every span sharing a trace ID as one connected waterfall, making it immediately visible which specific hop in a multi-service chain was actually slow.
Q: What replaced Spring Cloud Sleuth, and why does it matter?
Spring Cloud Sleuth is no longer developed as its own separate project — its tracing functionality moved into Micrometer Tracing, the same facade Actuator's /metrics endpoint is already built on, extended to also handle trace/span propagation. This matters because it unifies metrics and tracing under one instrumentation model instead of two separate libraries, and because Spring Boot auto-instruments HTTP calls and RestClient/WebClient usage through it automatically once the tracing bridge and a reporter (like Zipkin's) are on the classpath.
Q: How does Spring Cloud Stream let application code stay independent of whether the broker is Kafka or RabbitMQ?
Spring Cloud Stream defines a broker-agnostic model built around plain java.util.function interfaces (Supplier, Function, Consumer) bound declaratively to named channels in configuration; a binder dependency (the Kafka binder or the RabbitMQ binder) is the piece that maps those channels onto the actual broker's topics/exchanges. Swapping brokers is, in principle, a matter of swapping the binder dependency and adjusting configuration — the Consumer<OrderPlacedEvent> bean itself never references Kafka or RabbitMQ directly.
Q: Why does a consumer group matter in Spring Cloud Stream, and what happens if you forget to set one?
A consumer group determines whether multiple instances of the same service share incoming events (load-balanced, each event delivered to exactly one instance in the group) or each receive every event independently. Without an explicit group, multiple running instances of the same consuming service may each independently receive and process every event, causing duplicate processing (e.g. double-reserving stock for the same order) instead of sharing the load as intended — a subtle bug that only appears once a consumer is scaled beyond a single instance.