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 + indicesRegistration 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_checksis 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/:
- Pull the canonical catalog view for this node from the server.
- Compare against
local.State. - 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 inagent/check.go. - Add a catalog endpoint in
agent/consul/catalog_endpoint.goand an HTTP handler inagent/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.