Skip to content

Consul:对象、生命周期与一致性模型 ​

Consul 服务发现入门与阅读环境 ​

版本与前置 ​

本文以 Consul Community 1.20.x 的 HTTP v1 服务发现接口为教学边界,Node.js 22 提供 fetch。这里的 v1 是接口路径,不代表 Consul 1.0。读者需要理解 IP、端口、HTTP 状态码与 DNS;不需要 Kubernetes 或服务网格基础。本文不覆盖 Enterprise namespace、partition 与 Connect 数据平面。核对日期为 2026-10-17;版本族用于约束语义,不表示该旧版本仍适合新生产部署。升级前需重新核对安全公告和接口。

本站是理论笔记项目,全部示例未执行,没有启动服务、Docker 或安装产品依赖。后文命令供读者在自己已获授权的实验环境运行;预期结果是接口合同推导,不是实测记录。

客户端与服务端 ​

Consul agent 接收本机服务注册;server 通过 Raft 保存权威目录,客户端 agent 不因名称中的 client 就等于业务调用方。业务程序从发现接口取得地址后,仍要自己建立连接、设置超时和重试。注册中心不代替业务代理,也不会保证刚查询到的地址在下一毫秒仍可用。

Consul 服务注册 应区分服务名和实例 ID:notes-api 是一类服务,notes-api-reader-lab 是本 agent 上的一份实例。实例端口 8080 是业务端口,8500 是 Consul HTTP 端口,8600 通常是 DNS 端口。把注册中心地址当业务地址调用会得到完全不同的协议响应。

读者命令与静态文件 ​

Consul 命令速查 从只读的 catalog services 开始,它列服务名,不承诺返回健康实例。读者已有 CLI 和已配置身份时可用 consul catalog services;环境变量 CONSUL_HTTP_ADDR 指向 HTTP 地址,CONSUL_HTTP_TOKEN 提供调用身份。不要把 token 写进共享命令历史。完整 HTTP 客户端见应用篇。

sh
consul catalog services
curl --fail-with-body -H "X-Consul-Token: $CONSUL_HTTP_TOKEN" "$CONSUL_HTTP_ADDR/v1/health/service/notes-api?passing=true"

shell 示例采用 POSIX 环境变量写法;PowerShell 需要 $env:CONSUL_HTTP_ADDR,并使用 curl.exe 避免别名差异。HTTP 返回 200 且数组为空是一种正常业务结果;curl 的成功退出不意味着有健康实例。

第一组练习与解答 ​

题目:两个实例同名、不同 ID 是否冲突?catalog 有 notes-api,为什么应用仍可能无法调用?先写出三种解释。

参考解答:同名允许聚合发现;同 agent 使用相同 ID 可能覆盖实例定义。catalog 存在只说明登记存在,health 可能过滤 critical 实例,ACL 可能过滤结果,或者 Address/Port 对消费端不可路由。排查要依次比较相同身份、相同数据中心和相同服务名的目录与健康响应,再检查消费者到业务地址的网络,不要先删除数据目录。

来源与边界 ​

中英文检索词为“Consul 服务发现 健康检查 ACL”与“Consul catalog health blocking queries”。最终依据为官方 Agent service API、Catalog CLI 与 Health API。历史安装页保留 URL;其 dev/bootstrap、公网监听及清目录建议不能直接当作生产操作流程。

Consul 目录健康 DNS 与阻塞查询 ​

catalog 与 health ​

Consul catalog health 的职责不同:catalog 记录节点和服务,health 提供检查状态并可按 passing 过滤。注册成功说明目录接受了定义,不能推出进程正在监听、依赖数据库可用或消费者可访问。实例通常通过本机 agent 注册,使 agent 的状态管理和检查生命周期一致;不要随意绕过 agent 写 catalog 后,又期待本机反熵同步长期保留这份记录。

Consul TTL 检查 要由真实拥有服务生命周期的程序续报。示例服务初始 critical,避免还没准备好就入流;读者可在确认业务已可用后调用 check/pass。TTL 到期会变为 critical,而 DeregisterCriticalServiceAfter 是持续失败后的清理阈值,两者不是同一计时器。短暂失败不能证明应该马上删除实例;反之,把检查永远设 passing 会掩盖故障。

DNS 的结果边界 ​

Consul DNS SRV 能同时表达目标主机和端口,A/AAAA 只表达地址。消费者若只取 A 后硬编码端口,就丢失了注册端口。notes-api.service.consul 是服务查询名,不能假设操作系统默认解析器已经把 consul 域转发到 Consul DNS。DNS 响应还受健康过滤、缓存 TTL、报文长度以及 agent 使用的 ACL 身份影响,因而它不是 HTTP catalog 的逐字段镜像。

若 HTTP 能发现但 DNS 无结果,先确认请求确实到 8600、名称包含正确数据中心、服务检查状态以及 DNS agent 的 default token。HTTP 请求携带的 token 不会自动附着到普通 DNS 请求。DNS 记录即使仍被缓存,也不意味着实例仍然健康,业务端仍须处理连接失败。

blocking query 游标 ​

Consul blocking query 使用响应头 X-Consul-Index 作为下一次 index 参数,wait 控制最长等待。返回只表示可能有变化或等待结束;客户端必须重新读取完整快照,而不能把每个响应当一条不丢失的事件。超时返回的 index 可能没变,业务应允许重复快照。

Consul index 回退 可能发生在状态恢复等场景;继续持有比服务端更大的游标会错过变化,应清零重建查询。收到零索引时要将后续等待游标至少设为 1,并限制重试频率,防止紧密循环。示例还设总请求超时 70 秒,大于 30 秒 wait 和服务端可能增加的抖动;它仅演示两轮读取,不是可直接部署的无限订阅守护程序。

身份决定可见集合 ​

Consul ACL 过滤 会让读取结果只包含当前身份有权限的部分,200 空数组不等于系统不存在服务。检查 X-Consul-Results-Filtered-By-ACLs 响应头,有过滤标记时不能把空结果解释为全局故障。service:read 与 node:read 依据端点共同决定可见数据;应用只读发现不应拿管理 token。ACL 是注册中心 API 的授权层,不自动保护业务端口,业务通信的认证仍需单独设计。

练习与解答 ​

题目:目录有两台,passing 查询只有一台,DNS 缓存还有两台,是否违反一致性?答:三个观察经过不同过滤和缓存,不可直接比较。先统一身份与数据中心,再比较健康检查快照,最后查解析器 TTL。题目:同一个 index 重复返回是否应丢弃响应?答:仍要校验响应与健康地址集合,去重业务更新可以,但不能把索引不变当协议故障。

核对日期 2026-10-17,适用 Consul 1.20.x;依据官方 blocking queries、DNS 查询、ACL rules。本文解释传统阻塞查询,不将其他端点的 hash 模式混入 index 合同。

本页为理论说明,关联示例未执行;没有连接服务或验证分布式时序。

继续阅读