两种不同的发现
etcd 常被用作 Discovery Service(服务发现组件),但一个自然的问题是:etcd 自身怎么被 etcd client 发现呢?
这里需要区分两件事:
- 集群启动时的自我发现:一般用初始集群配置即可完成,用于让各节点互相找到对方组成集群;
- 客户端发现 etcd 集群:应用作为客户端,需要找到可用的 etcd 节点来读写数据。
DNS discovery 正是作为客户端发现 etcd 集群的机制。
discovery-srv 参数
etcd 客户端提供了 -discovery-srv 参数,可以用来指定找到 etcd 集群的域名。客户端拿到这个域名后,会去查询对应的 DNS SRV 记录,从中得到集群各节点的主机名与端口。
这样做的好处是:应用配置里只需要写一个稳定的域名,而不需要维护一份会经常变动的节点地址列表。
SRV 记录的查找顺序
客户端在发现时会按以下顺序查找 DNS SRV 记录:
_etcd-client._tcp.example.com_etcd-client-ssl._tcp.example.com
按这个顺序被查找,说明存在一个优先级关系:先尝试明文客户端对应的记录,再尝试 TLS 客户端对应的记录。
这里只介绍 client 的 discovery。集群自身的启动发现走的是另一套流程,使用初始集群参数完成。
相比硬编码地址的优势
把节点地址写死在配置文件里,看起来简单,但在集群生命周期中会不断制造麻烦:
- 扩容时:新增节点需要通知所有客户端修改配置,否则客户端永远连不到新节点;
- 故障替换时:节点下线或更换 IP,所有客户端配置都得同步更新;
- 环境差异:开发、测试、生产环境的地址不同,配置容易混淆出错;
- 变更成本:每次变更多少会涉及配置管理与服务重启,运维负担与出错概率同步上升。
而使用 DNS 记录后,这些变更都收敛到 DNS 层:客户端只认域名,节点信息的更新通过修改 SRV 记录完成,应用侧无需改动、无需重启。
落地时的注意事项
- 正确配置 SRV 记录:记录中需要包含目标主机与端口,缺失端口会导致客户端无法建立连接;
- 区分明文与 TLS 场景:启用 TLS 的环境应使用对应的 ssl 记录名,并确保证书校验配置一致;
- DNS 本身要高可用:DNS 成为发现链路的关键依赖后,它自身的可靠性直接决定客户端能否启动;
- 注意解析缓存与 TTL:TTL 设置过长会让节点变更滞后生效,过短则增加 DNS 查询压力,需要按变更频率取平衡;
- 保留兜底手段:极端情况下可提供静态节点列表作为备选,避免 DNS 故障直接导致应用无法启动。
小结
etcd client DNS Discovery 的价值在于把「集群在哪里」这个问题从应用配置中解耦出去。-discovery-srv 加一条 SRV 记录,就让客户端具备了跟随集群变化自动调整的能力。对于任何需要长期运行、节点会不断增减的分布式系统,这都是一个值得采用的模式。
| 配置参数 | -discovery-srv 指定用于定位 etcd 集群的域名 |
|---|---|
| 首查记录 | _etcd-client._tcp.<域名>,用于明文客户端场景 |
| 次查记录 | _etcd-client-ssl._tcp.<域名>,用于启用 TLS 的场景 |
| 记录内容 | SRV 记录返回目标主机与端口,客户端据此建立连接 |
| 主要收益 | 节点增删只改 DNS,客户端配置无需变更、无需重启 |