skip to content

Consul Discovery & KV

Consul registers services with health checks and doubles as a key-value config store, backed by Raft for the catalog and gossip for membership. Interviewers contrast it with Eureka on consistency and on doing two jobs at once.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

How does a Spring Boot service register itself with HashiCorp Consul for service discovery, and what dependency/config is required?

level: juniorimportance: must knowfreq 70%

answer

  1. starter-consul-discovery on classpath
  2. agent at localhost:8500
  3. spring.application.name = service ID
  4. auto-register + DiscoveryClient
  5. config.import replaces bootstrap

basics

~10 s

Add the spring-cloud-starter-consul-discovery dependency. On startup the app auto-registers with a local Consul agent using its service name and port, so other services can look it up by name.

solid answer

~30 s

You add `spring-cloud-starter-consul-discovery` to the classpath. Spring Cloud Consul's auto-configuration then registers the application with a Consul agent (default `localhost:8500`) at startup, using `spring.application.name` as the service ID and the app's host/port. Registration is enabled by default and driven by `spring.cloud.consul.discovery.*` properties. Consul stores this in its service catalog. Other services discover it through Spring Cloud's `DiscoveryClient` abstraction, or transparently via a load-balanced `RestTemplate`/`WebClient` using the service name as the host. On shutdown the app deregisters. You point it at Consul with `spring.cloud.consul.host` and `spring.cloud.consul.port`. Consul must be reachable (usually a local agent) for registration to succeed.

code

yaml · 17 lines
yaml
# build.gradle: implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
spring:
  application:
    name: order-service
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${random.value}
        tags:
          - version=1.0
---
# Consuming another service by name:
# @LoadBalanced @Bean RestTemplate rt;
# rt.getForObject("http://payment-service/charge", ...);

go deeper

for a junior

Know: add the discovery starter, app auto-registers with an agent using its service name, others find it by name.

for a middle

Know the key properties (instance-id uniqueness, prefer-ip-address, fail-fast) and the DiscoveryClient/LoadBalancer wiring.

for a senior

Explain agent vs server, the config.import vs bootstrap change, deregistration and startup failure modes.

for a principal

Reason about registration at scale: instance-id collisions, container networking, fail-fast policy, and Consul as one option among Eureka/K8s discovery.

**What Consul is.** HashiCorp Consul is a service mesh / service-discovery tool. It maintains a *catalog* of which service instances (name, IP, port, health) are currently available, so services can find each other by logical name instead of hardcoded addresses. It also provides a distributed **KV store** (a hierarchical key/value database) and a health-checking subsystem. **The Consul agent.** Every machine runs a Consul *agent*. Agents run in two modes: **client** agents (lightweight, forward requests to servers) and **server** agents (hold state, participate in Raft consensus). Your Spring app talks to a local agent, typically at `localhost:8500` (the HTTP API port). The agent relays registrations to the server cluster. **Spring Cloud Consul.** The `spring-cloud-starter-consul-discovery` starter pulls in auto-configuration (`ConsulAutoConfiguration`, `ConsulDiscoveryClientConfiguration`, `ConsulAutoServiceRegistrationAutoConfiguration`). Simply having it on the classpath enables: - **Auto-registration**: at startup a `ConsulServiceRegistry` / `ConsulAutoServiceRegistration` registers the instance with the agent. The service name defaults to `spring.application.name`; the instance ID defaults to `${spring.application.name}-${server.port}` (or a random suffix). Registration data includes host, port, tags, and a health check. - **Discovery**: a `ConsulDiscoveryClient` implements Spring Cloud's `DiscoveryClient`, letting you call `getInstances("service-name")`. Combined with Spring Cloud LoadBalancer, a `@LoadBalanced RestTemplate`/`WebClient` can use `http://service-name/...` and resolve+balance across healthy instances. **Key properties** (all under `spring.cloud.consul`): - `host` / `port` — the agent (default `localhost` / `8500`). - `discovery.enabled` — turn registration/discovery on/off (default true). - `discovery.service-name` — override the registered name. - `discovery.instance-id` — override the instance ID (make it unique per instance!). - `discovery.register` / `discovery.deregister` — whether to register / deregister on shutdown. - `discovery.prefer-ip-address` — register the IP instead of hostname (common in containers). - `discovery.tags` — arbitrary tags used for filtering. **Bootstrap ordering gotcha.** Historically Consul config was read during the *bootstrap* phase, requiring `spring-cloud-starter-bootstrap` or `spring.cloud.bootstrap.enabled=true`. Modern Spring Cloud uses the **`spring.config.import`** mechanism instead (e.g. `spring.config.import=consul:` for config), so bootstrap is no longer required for KV config. Discovery itself doesn't need bootstrap. **Gotchas / edge cases.** - If no Consul agent is reachable at startup, registration fails; `spring.cloud.consul.discovery.fail-fast` (default true) controls whether the app fails to start or logs and continues. - Duplicate instance IDs cause instances to overwrite each other in the catalog — always ensure uniqueness (default appends a random value in newer versions). - In containers, `prefer-ip-address=true` avoids registering an unroutable container hostname. **When to use.** Choose Consul discovery when you already run Consul (or want its KV/health/mesh features), need multi-datacenter awareness, or want language-agnostic discovery. Alternatives in the Spring Cloud ecosystem include Eureka and Kubernetes-native discovery.

  • What is the difference between a Consul client agent and a server agent?
    Client agents are stateless: they run on every node, register local services, run health checks, and forward RPCs to servers. Server agents hold the replicated catalog/KV state and participate in Raft consensus. Apps normally talk to a local client agent.
  • Do you still need spring-cloud-starter-bootstrap for Consul?
    Not for discovery, and no longer for KV config either — modern Spring Cloud uses `spring.config.import=consul:` instead of the bootstrap context. Bootstrap is only needed on older setups or when explicitly enabled.

context

open as a page

How do Consul health checks work with a Spring Boot app, and what happens to an instance that becomes unhealthy?

level: middleimportance: should knowfreq 55%

basics

~10 s

By default Spring registers an HTTP check hitting the app's Actuator health endpoint. The agent polls it periodically; if it fails, Consul marks the instance unhealthy and discovery stops routing traffic to it.

open as a page

How is the Consul KV store used as a configuration backend for Spring Boot, and how do property keys map into the environment?

level: middleimportance: should knowfreq 50%

basics

~10 s

Add spring-cloud-starter-consul-config and import consul: config. Spring reads keys under a prefix like config/<app-name>/ from Consul's KV store and exposes them as normal Spring properties, with app-specific keys overriding shared ones.

open as a page

Explain how Consul keeps its service catalog and KV store consistent, and how it tracks cluster membership — i.e. Raft vs gossip.

level: seniorimportance: should knowfreq 40%

basics

~20 s

Consul servers use the Raft consensus algorithm to keep one consistent, replicated copy of the catalog and KV store (writes go through an elected leader). Membership and failure detection use a gossip protocol (Serf/SWIM) across all agents.

open as a page

When would you choose Consul over Eureka for service discovery in a Spring Cloud system, and what architectural trade-offs are you accepting?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Choose Consul when you also want a consistent KV config store, health checking, multi-datacenter, and language-agnostic discovery in one tool. The trade-off is a CP system that can reject writes during partitions, versus Eureka's AP always-writable design.

open as a page