入门:Consul 定义、四大功能与 Agent 拓扑
基于 Consul 1.18 · 核于 2026-08
速查
- 定义:Consul 是 HashiCorp 出品的分布式服务网格 + 服务发现平台,一个 Go 二进制打包「服务发现 + 健康检查 + KV 存储 + 多数据中心 + Connect mesh」五大能力,CP 型(Raft 强一致)。
- 四大功能:①服务发现(Agent 注册,DNS/HTTP 查询,服务目录走 Raft 强一致);②健康检查(HTTP/TCP/Script/Docker 探活,
passing/warning/critical三态);③KV 存储(层级化键值,Watch 长轮询,配合 Session 做领导选举/分布式锁);④Connect mesh(Sidecar 或原生集成,自动 mTLS + Intentions 授权)。 - 架构:Server + Client Agent:Server(建议 3/5 个,Raft 仲裁,存目录强一致);Client Agent(每节点一个,无状态,跑在所有机器上做注册/健康检查/Gossip)。两者用 Gossip(LAN Serf) 互联。
- Raft vs Gossip 分工:Raft(强一致)管「服务目录、KV」——写要过半 Server 同步;Gossip(最终一致)管「节点存活、故障检测、广播」——Server 间用 WAN Gossip 跨 DC,节点内用 LAN Gossip 收集 Client 存活。
- 健康检查三态:
passing(健康,可被查询)、warning(告警,仍可被查,用于软降级)、critical(致命,从查询结果摘除)。检查类型:HTTP(200=passing)、TCP(能连即 passing)、Script(退出码 0=passing)、Docker(容器状态)、TTL(服务主动上报,超时自动 critical)。 - 反向探 vs 主动报:Consul 默认反向探——Agent 主动去探服务(HTTP/TCP),服务被动被探;TTL 模式才是服务主动上报「我还活着」,超时不报即 critical。Nacos 默认是主动上报。
- DNS 接口:
<service>.service.consul直接解析出健康实例 IP,非 JVM/老应用零改造接入;HTTP 接口给 SDK 用。 - 多数据中心:每个 DC 一套 Server 集群,WAN Gossip 把多 DC 互联,跨 DC 查询走 WAN,开箱即用。
- CP 定位:Consul 是CP(强一致优先,网络分区时宁可拒绝写也不返回脏数据),与 Nacos(默认 AP)/etcd(CP,但纯 KV)定位不同。
- 进阶顺序:服务发现与健康检查 → 生态与对比 → 参考。
一、Consul 是什么:分布式服务通讯录
微服务架构下,服务实例动态增减(容器扩缩容、节点宕机、滚动发布),调用方不能再用硬编码 IP。需要一个注册中心:服务启动时登记「我叫 order-service,IP 是 10.0.0.5,端口 8080」,调用方查询时拿到当前健康实例列表。Consul 就是干这个的,但它不止做注册中心:
- 服务发现(Service Discovery):维护一个「服务名 → 健康实例列表」的目录,提供 DNS 和 HTTP 两种查询方式。这是核心。
- 健康检查(Health Checking):Agent 周期性探活每个注册的实例,挂掉的实例从目录里摘掉,调用方永远拿到「健康」的实例。
- KV 存储(Key-Value Store):一个层级化的 KV(类似文件系统路径),可存配置、做领导选举(配合 Session)、做分布式锁。
- 多数据中心(Multi-Datacenter):原生支持跨 DC 组网,WAN Gossip 互联,不用自建联邦。
- Connect 服务网格:Sidecar 或原生集成,自动给服务间流量加 mTLS,用 Intentions 做授权(谁能调谁)。
一句话:Consul 是 CP 型的「服务发现 + 健康检查 + KV + 多 DC + mesh」一站式平台,强一致靠 Raft,故障检测靠 Gossip。
二、架构:Server 与 Client Agent
Consul 用两层架构:Server(少数、强一致)+ Client Agent(多数、每节点一个)。
┌─────────────────── 数据中心 DC1 ───────────────────┐
│ │
WAN Gossip │ ┌─── Server 集群(Raft,3 或 5 个)───┐ │
(跨 DC) │ │ Server1 ←Raft→ Server2 ←Raft→ Server3 │
│ │ │ │ │ │
│ └─────┼──────────────┼─────────────┘ │
│ │ LAN Gossip(Serf) │
│ ┌─────┴──────────────┴─────────────┐ │
│ │ Client Agent Client Agent Client Agent │
│ │ (节点 A) (节点 B) (节点 C) │
│ │ │ app │ app │ app │
│ └───┼──────────────┴──────────────┴───────────────┘
└───────┼─────────────────────────────────────────────┘
│ 服务注册/健康检查在本地 Agent 完成
│ 目录同步走 Raft(Server 间强一致)- Server:少数几个(3 或 5,奇数为了 Raft 仲裁),存服务目录 + KV,写请求要过半 Server 通过 Raft 同步才算成功。是强一致与持久化的承担者。Server 自己之间也跑 Raft + Gossip(LAN Serf,用于故障检测——某个 Server 挂了,Gossip 立刻发现,Raft 重新选主)。
- Client Agent:每台机器一个,无状态(不持久化目录),职责是①接收本机服务的注册;②跑健康检查(探本机服务);③把注册信息和检查结果转发给 Server;④参与 LAN Gossip。Client Agent 是「本地代表」,让注册和健康检查就近完成,不必每个服务都跨网络找 Server。
- 为什么分两层:如果所有服务直连 Server,Server 压力大、健康检查跨网络慢。Client Agent 把「注册 + 探活」下沉到每台机器本地,Server 只管目录一致性。这是 Consul 比「单层注册中心」(如 Eureka)扩展性好的关键。
三、Raft 与 Gossip:强一致 + 最终一致的分工
Consul 同时用两个共识机制,各管一摊:
| 机制 | 用途 | 一致性 | 代价 |
|---|---|---|---|
| Raft | 服务目录、KV 的写同步 | 强一致(过半提交) | 写延迟较高(要等多数派 ack),分区时少数派不可写 |
| Gossip(Serf) | 节点存活检测、成员管理、广播 | 最终一致(概率传播) | 快、可扩展,但不保证强一致 |
- Raft 管目录:当服务注册(
agent service register),Client Agent 把注册信息发给 Server,Server 用 Raft 把这条记录同步到过半 Server 后才算注册成功。查询任意 Server 都返回一致结果——这是 CP。 - Gossip 管探活:节点是否活着用 Gossip(Serf 库)。每个 Agent 周期性向随机几个邻居发「我还活着」,邻居再转发,几秒内全网都知道某节点挂了。Gossip 快、可扩展(O(log N) 传播),适合「节点存活」这种不需要强一致的场景。
- WAN Gossip:跨 DC 用 WAN Gossip 把多个 DC 的 Server 互联,跨 DC 查询时一个 DC 的 Server 能转发到另一个 DC。
四、健康检查:三态与探活方式
健康检查是 Consul 的灵魂——它决定「哪些实例能被查询到」。每个检查有三种状态:
passing(健康):实例在查询结果里,正常路由。warning(告警):实例仍可被查(除非查询时显式过滤),用于「软降级」(如磁盘 80%、延迟升高但还能服务)。critical(致命):实例从查询结果摘除,不再被路由。
检查类型(注册时指定):
| 类型 | 原理 | passing 条件 |
|---|---|---|
| HTTP | Agent 周期性 GET 一个 URL | 返回 2xx(429=warning,其他=critical) |
| TCP | Agent 尝试 TCP 连接端口 | 能建立连接 |
| Script | Agent 执行一段脚本/命令 | 退出码 0(1=warning,其他=critical) |
| Docker | 查容器状态(需与本机 docker daemon 通信) | 容器 running |
| gRPC | gRPC 健康检查协议(grpc.health.v1) | SERVING |
| TTL | 服务主动调 API 「我还活着」 | 在 TTL 内上报过(超时=critical) |
- 默认是反向探:HTTP/TCP/Script 都是 Agent 主动去探服务,服务被动被探。这是 Consul 的默认模式。
- TTL 是主动报:服务自己周期性调
agent check pass上报,适合「服务最清楚自己健康」的场景(如队列消费者,Agent 外部探不出来它卡死了)。
五、Consul 的定位:CP 型服务发现
注册中心有 CP 与 AP 之争:
- CP(强一致优先):Consul(Raft)、etcd(Raft)、ZooKeeper(ZAB)。网络分区时,少数派分区拒绝写(不可用),保证读到的数据一定一致。适合「宁可查不到,也不能查到已死实例」的场景。
- AP(可用优先):Eureka、Nacos(AP 模式)。网络分区时各分区都能读写,但可能读到旧数据(短暂不一致)。适合「高可用优先,能容忍短暂脏读」的场景。
Consul 选 CP 的理由:服务发现如果读到已死实例,调用方会请求失败,比「短暂查不到」更糟。所以 Consul 在分区时宁可让少数派 Agent 暂时不能注册(等分区恢复),也要保证目录一致。
下一步
理解了 Consul 的定位与架构后,下一步深入服务发现与健康检查——Agent 注册、DNS/HTTP 查询、四大检查类型、KV 与 Connect mesh 的实战,以及生态与对比——Spring Cloud Consul 生命周期与 Nacos/etcd 的横向对比。