跳转至

599_Consul服务发现

一句话概述:HashiCorp Consul 是分布式服务发现和配置管理工具,让微服务之间能自动找到彼此(服务发现),同时提供健康检查、KV 存储、服务网格(Service Mesh)和多数据中心支持,是微服务架构的"电话簿+健康管家"。

核心知识点表

概念白话解释
Service Discovery服务发现,服务自动注册和查找(不用硬编码 IP)
Health Check健康检查,定期检测服务是否正常运行
KV Store键值存储,集中管理配置(类似 etcd)
Service Mesh服务网格,通过 Sidecar 代理管理服务间通信
Agent代理,每个节点上运行的 Consul 进程(Server 或 Client)
Catalog服务目录,所有注册服务的中心数据库
ConnectConsul 的服务网格功能,提供 mTLS 加密和访问控制

安装配置

安装 Consul

# macOS
brew install consul                      # Homebrew 安装

# Ubuntu/Debian
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install consul

# Docker
docker run -d --name consul \
  -p 8500:8500 \                        # Web UI 和 HTTP API
  -p 8600:8600/udp \                    # DNS 接口
  hashicorp/consul:latest agent \
  -dev \                                # 开发模式
  -client=0.0.0.0                       # 允许外部访问

# 验证安装
consul version                           # 查看版本(当前 v1.22.x)
# 访问 http://localhost:8500 查看 Web UI

生产集群部署

# server.hcl — Server 节点配置
datacenter = "dc1"                       # 数据中心名
data_dir   = "/opt/consul/data"          # 数据目录
server     = true                        # Server 模式
bootstrap_expect = 3                     # 期望 3 个 Server 节点

bind_addr = "{{ GetPrivateInterfaces | attr \"address\" }}"  # 绑定私网 IP

ui_config {
  enabled = true                         # 启用 Web UI
}

client_addr = "0.0.0.0"                  # 允许外部访问 API

connect {
  enabled = true                         # 启用服务网格
}

# ACL 配置(生产必须)
acl {
  enabled        = true                  # 启用 ACL
  default_policy = "deny"               # 默认拒绝
  enable_token_persistence = true        # Token 持久化
}
# 启动 Server 集群
# 节点1
consul agent -config-file=server.hcl

# 节点2、3 加入集群
consul agent -config-file=server.hcl -retry-join=SERVER1_IP

# Client 节点(运行在应用服务器上)
consul agent -data-dir=/opt/consul/data \
  -retry-join=SERVER1_IP \              # 加入集群
  -bind=LOCAL_IP                        # 本机 IP

基本使用

服务注册

// 方法1:配置文件注册
// /etc/consul.d/web-service.json
{
  "service": {
    "name": "web",                       // 服务名
    "port": 8080,                        // 服务端口
    "tags": ["v1", "production"],        // 标签
    "check": {                           // 健康检查
      "http": "http://localhost:8080/health",  // 检查 URL
      "interval": "10s",                // 每 10 秒检查一次
      "timeout": "3s"                   // 超时 3 秒
    }
  }
}
# 重新加载配置
consul reload                            # 重新加载服务定义

# 方法2:HTTP API 注册
curl -X PUT http://localhost:8500/v1/agent/service/register \
  -d '{
    "Name": "api-service",
    "Port": 3000,
    "Tags": ["v2"],
    "Check": {
      "HTTP": "http://localhost:3000/health",
      "Interval": "10s"
    }
  }'

# 方法3:CLI 注册
consul services register web-service.json  # 注册服务
consul services deregister web-service.json  # 注销服务

服务发现

# === DNS 方式(推荐) ===
# Consul 内置 DNS 服务器(端口 8600)
dig @localhost -p 8600 web.service.consul  # 查询 web 服务的 IP
# 返回所有健康的 web 服务实例 IP

dig @localhost -p 8600 web.service.consul SRV  # 查询包含端口的 SRV 记录

# 带标签查询
dig @localhost -p 8600 v1.web.service.consul  # 只查 v1 标签的实例

# === HTTP API 方式 ===
curl http://localhost:8500/v1/catalog/service/web  # 查询服务
curl http://localhost:8500/v1/health/service/web?passing  # 只返回健康的

# === CLI 方式 ===
consul catalog services                  # 列出所有服务
consul catalog nodes                     # 列出所有节点

KV 存储

# 写入配置
consul kv put config/db/host "db.example.com"     # 写入键值
consul kv put config/db/port "5432"                # 写入端口
consul kv put config/app/settings @settings.json   # 从文件写入

# 读取配置
consul kv get config/db/host             # 读取值
consul kv get -detailed config/db/host   # 读取详细信息(含版本)

# 列出键
consul kv get -recurse config/           # 列出 config/ 下所有键值

# 删除键
consul kv delete config/db/host          # 删除单个键
consul kv delete -recurse config/old/    # 递归删除

# 导出/导入
consul kv export config/ > backup.json   # 导出
consul kv import @backup.json            # 导入

高级用法

服务网格(Connect)

# 使用 Envoy Sidecar 代理实现 mTLS 和访问控制

# web-service.hcl — 带 Connect 的服务定义
service {
  name = "web"
  port = 8080

  connect {
    sidecar_service {                    # Envoy Sidecar
      proxy {
        upstreams {                      # 上游服务(要调用的服务)
          destination_name = "api"       # 目标服务名
          local_bind_port  = 9191        # 本地绑定端口
        }
      }
    }
  }
}
# web 服务通过 localhost:9191 访问 api 服务
# Consul 自动处理 mTLS 加密和服务发现
# 启动 Sidecar 代理
consul connect envoy -sidecar-for web    # 启动 web 的 Sidecar

# 配置访问意图(Intentions)
# 允许 web 访问 api
consul intention create web api          # 允许

# 禁止 web 访问 database
consul intention create -deny web database  # 拒绝

Consul Template(动态配置)

# 安装 consul-template
wget https://releases.hashicorp.com/consul-template/0.41.0/consul-template_0.41.0_linux_amd64.zip
unzip consul-template_*.zip
sudo mv consul-template /usr/local/bin/
# nginx.conf.ctmpl — Consul Template 模板
upstream backend {
{{ range service "api" }}                # 遍历所有 api 服务实例
    server {{ .Address }}:{{ .Port }};   # 动态生成 upstream
{{ end }}
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}
# 运行 consul-template
consul-template \
  -template "nginx.conf.ctmpl:nginx.conf:nginx -s reload"
# 监听 Consul 中 api 服务的变化
# 自动重新生成 nginx.conf 并 reload Nginx

多数据中心

# Consul 原生支持多数据中心
# 每个数据中心有自己的 Server 集群
# 通过 WAN Gossip 协议互相发现

# 查询远程数据中心的服务
dig @localhost -p 8600 web.service.dc2.consul  # 查询 dc2 的 web 服务
curl http://localhost:8500/v1/catalog/service/web?dc=dc2  # API 方式

常见报错

报错信息原因解决方案
No cluster leader没有 Leader 节点检查 Server 节点数(至少 3 个)
ACL not foundACL Token 无效创建或更新 Token
health check failing健康检查失败检查服务端口和检查 URL
rpc error: agent not foundAgent 未运行启动 Consul Agent
port already in use端口冲突修改端口或停止占用进程

速查表

# === 服务操作 ===
consul services register FILE   # 注册服务
consul services deregister FILE # 注销服务
consul catalog services         # 列出服务
consul catalog nodes            # 列出节点

# === KV 操作 ===
consul kv put KEY VALUE         # 写入
consul kv get KEY               # 读取
consul kv delete KEY            # 删除
consul kv export PREFIX         # 导出

# === 集群管理 ===
consul members                  # 查看集群成员
consul operator raft list-peers # 查看 Raft 节点
consul info                     # 查看信息
consul reload                   # 重新加载配置

# === 关键端口 ===
# 8500 → HTTP API 和 Web UI
# 8600 → DNS 接口
# 8301 → LAN Gossip(节点发现)
# 8302 → WAN Gossip(跨数据中心)
# 8300 → RPC(Server 间通信)

# === 健康检查类型 ===
# HTTP    → 检查 HTTP 端点
# TCP     → 检查 TCP 端口
# Script  → 运行脚本检查
# TTL     → 服务主动上报
# gRPC    → 检查 gRPC 端点

同类对比

特性ConsuletcdZooKeeperNacos
服务发现内置需扩展需扩展内置
健康检查内置有限内置
KV 存储内置核心核心内置
服务网格Connect
多数据中心原生有限有限有限
DNS 接口内置需 CoreDNS
学习曲线中等

选型建议:需要完整服务发现+服务网格选 Consul(功能最全);只需分布式 KV 存储选 etcd(K8s 默认使用);Java/Spring Cloud 生态选 Nacos(阿里开源)。