Consul — 多数据中心服务网格
架构概览
Consul 是 HashiCorp 出品的服务发现、配置管理和服务网格工具,原生支持多数据中心。
Data Center 1 (us-east) Data Center 2 (us-west)
┌─────────────────────┐ ┌─────────────────────┐
│ Server 1 (Leader) │◄────────►│ Server 4 (Leader) │
│ Server 2 │ WAN │ Server 5 │
│ Server 3 │ Gossip │ Server 6 │
│ │ │ │
│ Agent Agent Agent│ │ Agent Agent Agent│
│ (Client Mode) │ │ (Client Mode) │
└─────────────────────┘ └─────────────────────┘组件说明
| 组件 | 说明 |
|---|---|
| Server | 存储集群状态,参与 Raft 选举,建议 3 或 5 个 |
| Client(Agent) | 部署在每个服务节点,转发请求到 Server,执行健康检查 |
| Gossip 协议 | 节点发现和故障检测(LAN Gossip 和 WAN Gossip) |
| Raft 协议 | Server 间数据一致性 |
服务注册与健康检查
服务定义(JSON)
json
{
"service": {
"id": "order-service-1",
"name": "order-service",
"tags": ["v1.2", "primary"],
"address": "192.168.1.100",
"port": 8080,
"meta": {
"version": "1.2.0",
"env": "production"
},
"checks": [
{
"id": "http-check",
"name": "HTTP Health Check",
"http": "http://192.168.1.100:8080/actuator/health",
"interval": "10s",
"timeout": "3s",
"deregister_critical_service_after": "30s"
},
{
"id": "tcp-check",
"name": "TCP Check",
"tcp": "192.168.1.100:8080",
"interval": "10s"
}
]
}
}API 注册
bash
# 注册服务
curl -X PUT http://localhost:8500/v1/agent/service/register \
-H "Content-Type: application/json" \
-d @service.json
# 查询健康服务
curl "http://localhost:8500/v1/health/service/order-service?passing=true"
# 注销服务
curl -X PUT http://localhost:8500/v1/agent/service/deregister/order-service-1Spring Cloud Consul 集成
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>yaml
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: order-service
health-check-path: /actuator/health
health-check-interval: 10s
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
tags:
- version=1.2.0KV 存储(配置中心)
Consul 内置 KV 存储,可作为轻量级配置中心:
bash
# 写入配置
consul kv put config/order-service/db.url "jdbc:mysql://mysql:3306/orders"
consul kv put config/order-service/timeout "5000"
# 读取配置
consul kv get config/order-service/db.url
# 监听变更(长轮询)
consul kv get -wait=5m -index=<last-index> config/order-service/db.url
# 导入配置(JSON 格式)
consul kv import @config.jsonSpring Cloud Config + Consul
yaml
spring:
cloud:
consul:
config:
enabled: true
prefix: config
default-context: application
profile-separator: ','
format: YAML
data-key: data配置路径规则:
config/order-service,prod/data # 最高优先级
config/order-service/data
config/application,prod/data
config/application/data # 最低优先级Consul Connect(服务网格)
Consul Connect 提供基于 mTLS 的服务间安全通信:
hcl
# 服务配置(HCL 格式)
service {
name = "order-service"
port = 8080
connect {
sidecar_service {
proxy {
upstreams = [
{
destination_name = "payment-service"
local_bind_port = 9090
}
]
}
}
}
}bash
# 启动 Envoy Sidecar
consul connect envoy -sidecar-for order-serviceIntention(访问控制)
bash
# 允许 order-service 访问 payment-service
consul intention create order-service payment-service
# 拒绝所有到 db-service 的访问(默认拒绝)
consul intention create -deny '*' db-service
# 查看 Intention
consul intention list多数据中心
bash
# 查询其他数据中心的服务
curl "http://localhost:8500/v1/catalog/service/order-service?dc=us-west"
# 跨数据中心 DNS 查询
dig @127.0.0.1 -p 8600 order-service.service.us-west.consul
# 配置 WAN 联邦
consul join -wan <us-west-server-ip>ACL 安全配置
bash
# 启用 ACL
# consul.hcl
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
}
# 初始化 ACL(生成 bootstrap token)
consul acl bootstrap
# 创建服务 Token
consul acl token create \
--description "order-service token" \
--policy-name order-service-policy
# 创建 Policy
consul acl policy create \
--name order-service-policy \
--rules @order-policy.hclhcl
# order-policy.hcl
service "order-service" {
policy = "write"
}
service_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}故障处理案例
案例一:服务健康检查频繁失败
现象:服务实例频繁在 passing/critical 状态切换,导致流量抖动。
排查:
bash
# 查看健康检查详情
consul health checks order-service
# 查看 Agent 日志
journalctl -u consul -f常见原因与解决:
- 健康检查超时太短 → 调整
timeout和interval - 服务启动慢 → 增加
deregister_critical_service_after时间 - 网络抖动 → 使用 TCP 检查替代 HTTP 检查
案例二:Leader 选举频繁
现象:Consul Server 频繁发生 Leader 选举,集群不稳定。
排查:
bash
# 查看 Raft 状态
consul operator raft list-peers
# 查看集群成员
consul members -detailed原因:
- Server 节点资源不足(CPU/内存)
- 网络延迟过高(Raft 心跳超时)
- 时钟不同步
解决:
hcl
# 调整 Raft 超时参数
performance {
raft_multiplier = 1 # 默认 5,减小可加快选举但增加网络敏感性
}案例三:KV 数据不一致
现象:从不同 Server 读取 KV 数据不一致。
原因:默认读取使用 default 一致性级别(可能读到 Stale 数据)。
解决:
bash
# 强一致性读(必须从 Leader 读)
curl "http://localhost:8500/v1/kv/config/db.url?consistent"
# 最终一致性读(允许 Stale,性能最好)
curl "http://localhost:8500/v1/kv/config/db.url?stale"监控指标
bash
# Consul 内置 Telemetry
curl http://localhost:8500/v1/agent/metrics?format=prometheus| 指标 | 说明 |
|---|---|
consul.raft.leader | 是否为 Leader(1=是) |
consul.raft.commitTime | Raft 提交延迟 |
consul.catalog.service.query | 服务查询次数 |
consul.health.service.query | 健康检查查询次数 |
consul.serf.events | Gossip 事件数 |