Consul DNS 与 HTTP 服务发现
服务注册进 Consul 后有两种发现方式:HTTP API 查询返回结构化 JSON,精确可控;DNS 查询把服务名当域名解析,像用 DNS 一样拿 IP,对老系统改造最小。
DNS 命名格式
Consul 内置 DNS 服务器(默认 8600 端口),域名规则:
| 域名形态 | 含义 |
|---|---|
| <name>.service.consul | 当前数据中心内按服务名查实例 |
| <name>.service.<dc>.consul | 指定数据中心(第 14 章) |
| <tag>.<name>.service.consul | 按标签过滤,如 primary.web.service.consul |
| <name>.node.consul | 按节点名查询 |
dig 演示 A 记录
用 dig 指定 8600 端口解析 web 服务,返回健康实例的 IP 列表:
dig @127.0.0.1 -p 8600 web.service.consul
# ;; ANSWER SECTION:
# web.service.consul. 0 IN A 192.168.1.10
# web.service.consul. 0 IN A 192.168.1.11
一个域名对应多个 IP 时,Consul 默认把记录随机打乱返回(可配置轮询),客户端拿到多个 IP 各自做负载均衡即可。
SRV 记录查端口
A 记录只给 IP 不给端口,需要端口时查 SRV 记录:
dig @127.0.0.1 -p 8600 web.service.consul SRV
# ;; ANSWER SECTION:
# web.service.consul. 0 IN SRV 1 1 8080 主机名.node.consul.
# 返回里带端口 8080;SRV 的权重字段体现实例权重
HTTP 查询 API 对照
同样查 web 服务,HTTP 方式返回 JSON,适合程序直接消费:
| 需求 | DNS 写法 | HTTP API |
|---|---|---|
| 拿实例 IP | A 记录 | /v1/health/service/web?passing=true |
| 拿端口 | SRV 记录 | 返回体里的 Service.Port |
| 健康过滤 | critical 实例默认不返回 | 加 ?passing=true |
curl "http://127.0.0.1:8500/v1/health/service/web?passing=true"
DNS 默认只返回健康实例,critical 状态的不会出现在结果中,warning 的处理可借 dns_config.only_passing 微调。
客户端集成
集成方式随技术栈而定:Java 用 Spring Cloud Consul 自动注册与发现,Go 用官方 consul/api 库封装 HTTP 调用;遗留系统可把 Consul DNS 端口调到 53,或经 dnsmasq 转发,把服务域名当普通域名使用,业务代码零改动。
小结
DNS 发现胜在通用:会用 DNS 的语言都能消费,适合遗留系统平滑接入;HTTP 发现胜在结构化:端口、标签、健康状态、元数据一应俱全,是 SDK 与新系统的首选。两条路并存互补。