Open-Source Wikis

/

Consul

/

Features

/

Service discovery

hashicorp/consul

Service discovery

Consul's oldest and most widely used capability. Applications register services with their local agent; consumers look them up via DNS or HTTP. The catalog stays consistent across the cluster via Raft + anti-entropy.

Pieces

Piece Code
Service registration agent/agent_endpoint.go::AgentRegisterService, agent/local/state.go
Health checks agent/checks/, agent/check.go
Anti-entropy agent/ae/
Catalog (canonical store) agent/consul/state/catalog.go, agent/consul/catalog_endpoint.go
HTTP API agent/catalog_endpoint.go, agent/health_endpoint.go
DNS API agent/dns.go (see DNS interface)
Prepared queries agent/consul/prepared_query_endpoint.go, agent/consul/state/prepared_query.go

Registration flow

sequenceDiagram
    participant App as Application
    participant Agent as Local agent
    participant Local as agent/local.State
    participant Server as Server (catalog endpoint)
    participant FSM as Raft FSM

    App->>Agent: PUT /v1/agent/service/register {name, address, port, check}
    Agent->>Local: AddService + AddCheck
    Agent-->>App: 200 OK
    Note over Local,Server: anti-entropy goroutine
    Local->>Server: Catalog.Register (RPC)
    Server->>FSM: raftApply(RegisterRequest)
    FSM->>FSM: state.EnsureRegistration(...)
    FSM-->>Server: ok
    Server-->>Local: ok + indices

Registration via the agent (/v1/agent/service/...) is the recommended path because the agent owns the service lifecycle and runs the health checks. Direct catalog registration (/v1/catalog/register) bypasses the agent and is used for nodes that aren't running a Consul agent (legacy systems, external services).

Health checks

agent/checks/ implements the runners:

  • TTL — application periodically reports pass/warn/fail.
  • HTTP — agent issues a request and checks the status code.
  • TCP — agent opens a socket and checks reachability.
  • gRPC — agent makes a gRPC health-check call.
  • Script — agent execs a command (disabled unless enable_script_checks is set; security-sensitive).
  • Docker — agent execs a command inside a container.
  • OS Service — agent monitors a systemd or Windows service.
  • Alias — mirrors the health of another service.

Each runner reports state changes back to agent/local.State, which propagates through anti-entropy.

Lookup paths

Reader Endpoint
DNS web.service.consul, tag.web.service.consul, web.service.dc1.consul
HTTP catalog GET /v1/catalog/services, GET /v1/catalog/service/<name>
HTTP health GET /v1/health/service/<name>?passing (most common app endpoint)
Prepared queries GET /v1/query/<id>/execute, web.query.consul DNS
Streaming subscribe pbsubscribe over gRPC for catalog events (see Streaming)

The standard "discovery" pattern in client apps is GET /v1/health/service/<name>?passing with a blocking-query (?index= + ?wait=) so the app gets push-style notifications when the set of healthy instances changes.

Prepared queries

A prepared query is a saved, parameterized service query. It supports:

  • Failover — fail over to a list of DCs in order, or to "near" mode (closest DC by RTT).
  • Templates${match(1)} style templating to build per-call query targets.
  • Tag filters and near preferences.

Prepared queries are typically used for DNS-based failover (web.query.consul) when an operator wants automatic cross-DC failover without changing the client.

Implementation: agent/consul/prepared_query_endpoint.go, agent/consul/state/prepared_query.go. Templates are evaluated server-side so the client doesn't need to know about parameters.

Anti-entropy details

The anti-entropy loop in agent/ae/:

  1. Pull the canonical catalog view for this node from the server.
  2. Compare against local.State.
  3. Issue Raft-applied RPC writes for any drift (services or checks present locally but not in catalog, or vice versa).

The loop runs every agent.AntiEntropySync interval (defaults to ~60s) and on demand when local.State mutates.

Locality and segmentation

  • Datacenters — a service registered in DC1 is by default only visible in DC1; cross-DC discovery is opt-in via ?dc=... or DNS suffix.
  • Network segments (Enterprise) — an Enterprise feature that splits the LAN gossip into independent slices.
  • Partitions and namespaces (Enterprise) — multi-tenant boundaries that filter visibility.
  • Cluster peering — services tagged for export are visible to peers; see Cluster peering.

Integration points

  • DNS uses the catalog's blocking-query API through the agent cache.
  • Service mesh (Connect) uses the catalog to find target services and their proxies.
  • API gateway uses the catalog to bind routes to services.
  • Auto-encrypt / auto-config registers itself as a special service when bootstrapping.

Entry points for modification

  • Add a new health check kind in agent/checks/ and register it in agent/check.go.
  • Add a catalog endpoint in agent/consul/catalog_endpoint.go and an HTTP handler in agent/catalog_endpoint.go + agent/http_register.go.
  • Tune anti-entropy: agent/ae/.
  • Tune DNS lookup behavior: see DNS interface.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Service discovery – Consul wiki | Factory