当微服务实例在容器里频繁扩缩容、IP 不断变化,硬编码地址的调用方式立刻崩塌。Consul 是 HashiCorp 开源的服务发现与配置工具,用一套分布式 KV 存储、健康检查和 DNS 接口,让服务之间动态寻址、配置实时下发。本文从单节点起步,逐步覆盖服务注册、KV 配置中心、服务网格 mTLS,并给出可直接照抄的生产落地清单。
一、Consul 能解决什么问题
传统架构里,服务 A 调用服务 B 往往把地址写死在配置文件或代码里。一旦 B 扩容、漂移、重启,IP 就失效,调用方只能改配置重启。Consul 把”地址在哪”收归到统一注册表,并顺带提供配置与安全的横向能力:
- 服务发现:实例启动时自动注册,调用方通过 DNS(
web.service.consul)或 HTTP API 查询健康节点,无需硬编码。 - KV 存储:轻量配置中心,存特性开关、数据库连接串、限流阈值,支持 Watch 机制实时感知变更。
- 健康检查:主动探测 TCP/HTTP/gRPC 或脚本,不健康的节点自动移出服务列表。
- 服务网格 Connect:为服务间流量签发 mTLS 证书,实现零信任网络,与 Cilium 的 Kubernetes Zero-Trust 方案 思路一致。
二、与同类方案怎么选
KV 与注册中心赛道玩家很多,选型时最容易混淆。下面这张表把常见方案定位拉齐:
| 方案 | 核心定位 | 服务发现 | 配置管理 | 一致性 |
|---|---|---|---|---|
| Consul | 服务发现 + 配置 + 网格 | 原生强 | KV 支持 | Raft |
| etcd | K8s 底层 KV | 需自研 | 仅 KV | Raft |
| ZooKeeper | 老牌协调服务 | Znode 模拟 | 弱 | ZAB |
| Nacos | 阿里系注册/配置 | 强 | 强 | Raft/Distro |
如果你的目标是”服务发现 + 配置中心”一站式,且希望脱离 Kubernetes 也能用,Consul 是最省心的一个;已经在 K8s 体系内、只需要 KV,那就直接用 etcd。更系统的微服务治理实践可以配合网关一起看。
三、Docker Compose 快速起步
开发环境用单节点 dev 模式最快,一条命令就能起一个带 UI 的 Consul。生产务必用 server 集群(3 或 5 节点)并开启 ACL。
version: "3.8"
services:
consul:
image: hashicorp/consul:1.19
container_name: consul-dev
command: "agent -dev -client=0.0.0.0 -ui"
ports:
- "8500:8500" # HTTP API + UI
- "8600:8600/udp" # DNS
networks: [app]
networks:
app:
driver: bridge
启动后访问 http://localhost:8500 即可看到空注册表。配合 Docker 编排 把业务容器挂到同一网络,后续注册就水到渠成。
四、服务注册与发现
4.1 用配置文件注册
最常用的是把服务定义写成 JSON 放到 /etc/consul.d/,agent 启动时自动加载:
{
"service": {
"name": "web",
"port": 8080,
"tags": ["api", "v1"],
"check": {
"http": "http://localhost:8080/health",
"interval": "10s"
}
}
}
4.2 用 HTTP API 动态注册
容器化场景更推荐运行时注册,服务起来后主动 PUT 到 API:
curl -X PUT http://localhost:8500/v1/agent/service/register \
-H "Content-Type: application/json" \
-d '{
"Name": "order",
"ID": "order-1",
"Address": "10.0.0.21",
"Port": 9000,
"Check": {"HTTP": "http://10.0.0.21:9000/health", "Interval": "10s"}
}'
4.3 查询:DNS 与 HTTP
调用方无需引入 SDK,直接走 DNS 就能拿到健康节点(随机返回一个):
dig @127.0.0.1 -p 8600 web.service.consul
# 返回 web 服务的健康实例 A 记录
# 或 HTTP 查询,可拿全部实例
curl http://localhost:8500/v1/catalog/service/web
五、健康检查:把坏节点挡在门外
健康检查是服务发现可靠性的基石。除了上面 HTTP 探活,还支持 TCP、gRPC 与脚本。一个稍完整的检查定义:
{
"check": {
"id": "web-http",
"name": "HTTP /health on 8080",
"http": "http://localhost:8080/health",
"interval": "10s",
"timeout": "3s",
"deregister_critical_after": "30s"
}
}
deregister_critical_after 很关键:连续失败超过阈值就自动注销,避免雪崩时把流量打到已死实例。建议把健康检查端点做成”真健康”——连数据库、查依赖都通才返回 200,而不是永远 200 的假活。
六、KV 存储实战:配置中心与特性开关
KV 是 Consul 被低估的能力。它天然适合放运行时可变的配置,比如特性开关、限流阈值。
# 写入
consul kv put config/order/max_qps 2000
consul kv put feature/new_checkout true
# 读取
consul kv get config/order/max_qps
consul kv get -detailed feature/new_checkout
更实用的是 Watch 机制:配置变更时 Consul 主动回调你的服务,实现热更新,不必重启。下面是 Python 客户端监听某个 key 的示例:
import consul, time
c = consul.Consul(host="127.0.0.1")
index = None
while True:
index, data = c.kv.get("config/order/max_qps", index=index)
if data:
print("max_qps =", data["Value"].decode())
time.sleep(1) # 阻塞等待变更
七、Consul Connect:服务网格与 mTLS
Connect 给每个服务sidecar 代理自动签发证书,服务间调用强制 mTLS,调用方不再直接连后端,而是连本地代理。启用后还能用 intentions 做访问控制:
{
"service": {
"name": "web",
"port": 8080,
"connect": { "sidecar_service": {} }
}
}
# 只允许 api 访问 web
consul intention create -allow api web
这套零信任思路可以和 Cilium 网络策略 互补:Cilium 管 L3/L4 与 L7 网络层,Consul Connect 管服务身份与 mTLS,二者叠加更安全。
八、Consul Template:让配置自动跟随服务变化
光有注册表还不够,真正省事的是把”查询结果”自动渲染成配置文件。Consul Template 就是干这个的:它监听服务列表或 KV,一旦变化就重写 Nginx、HAProxy 等上游配置并 reload,无需人工介入。
upstream order_svc {
{{ range service "order" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
# consul-template 配置:变更即渲染并 reload
template {
source = "upstream.ctmpl"
destination = "/etc/nginx/conf.d/order_upstream.conf"
command = "nginx -s reload"
}
配合 Nginx 反向代理 使用,order 服务从 5 个实例缩到 2 个,upstream 会秒级同步,运维彻底告别手动改配置。这也是很多公司在还没上 K8s Service Mesh 之前,最稳妥的服务发现落地姿势。
九、与现有体系集成
Consul 很少单打独斗,落地时通常和这几块协同:
- 反向代理:用 Nginx 反向代理 做边缘入口,后端 upstream 通过 Consul Template 动态渲染,节点上下线无需手动改配置。
- Kubernetes:通过 Consul K8s 把 Pod 自动同步进 Consul 注册表,详见 Kubernetes 入门。
- 监控:Consul 暴露 Prometheus 指标,接 Prometheus + Grafana 看注册数、健康检查失败率。
- 网关:与 Spring Cloud Gateway 之类的网关配合,网关从 Consul 拉服务列表做路由。
十、生产落地检查清单
| 项目 | 建议 |
|---|---|
| 节点数 | server 用 3 或 5(奇数)组成 Raft 集群 |
| ACL | 生产必须开启 ACL,bootstrap 后下发策略 token |
| 健康检查 | 用”真健康”端点,配置 deregister_critical_after |
| TLS | 开启 gossip 与 RPC 加密,Connect 启用 mTLS |
| 持久化 | server 数据挂卷,避免重启丢注册状态 |
| 监控 | 接 Prometheus,告警 leader 切换与检查失败 |
十一、常见误区与排障
| 现象 | 根因 | 处理 |
|---|---|---|
| DNS 查不到服务 | 客户端没指向 8600 / 没挂同网络 | dig 指定 @consul_ip -p 8600 |
| 节点反复被注销 | 健康检查太严格或超时过短 | 放宽 timeout,确认端点真健康 |
| 集群脑裂 | server 数为偶数或网络分区 | 保持奇数节点,检查网络 |
| KV 读取延迟高 | 跨数据中心未设 LAN/WAN gossip | 配置 retry_join 与 advertise |
Consul 把”服务在哪、配置是什么、谁能调谁”三件事一次性收敛,是微服务体系里性价比极高的基础设施。从单机 dev 模式验证,到 K8s 接入、网关联动、mTLS 加固,路径清晰可控。把它作为你服务网格与配置中心的第一块基石,能省下大量手写注册与热更新的重复劳动。




