服务发现解决什么问题

分布式系统里,客户端需要知道它该连接哪些节点。把节点地址硬编码进配置文件的做法在集群扩容、故障切换时非常脆弱:一旦节点发生变化,就得逐个改配置并重启应用。

服务发现把这层信息从应用配置中抽出来:客户端只依赖一个稳定的服务标识,具体的节点列表由发现机制动态提供。etcd 既常被用作服务注册中心,它自身也需要一套被客户端发现的方式。

etcd 作为发现服务

etcd 提供高可用的键值存储与监听机制,很适合承担服务注册与配置同步的角色:

  • 服务注册:服务实例启动后把自身地址写入约定的键路径,并设置租约,实例退出后租约到期自动摘除;
  • 变更通知:客户端订阅键路径,节点列表变化时可及时收到通知,而不必轮询;
  • 配置分发:把需要动态调整的配置放在 etcd 中,各节点监听变更并热加载;
  • 选主与协调:借助租约与事务能力实现分布式锁和选主逻辑。

客户端如何发现 etcd 集群自身

一个自然的问题是:etcd 自己怎么被客户端找到?如果还是硬编码地址,就回到了原点。常用解法是借助 DNS SRV 记录

以 etcd 客户端为例,可以通过 -discovery-srv 参数指定用于定位集群的域名。客户端会按以下顺序查找 DNS SRV 记录:

  1. _etcd-client._tcp.example.com:明文通信场景;
  2. _etcd-client-ssl._tcp.example.com:启用 TLS 的场景。

SRV 记录会返回集群各节点的主机名与端口,客户端据此建立连接。这样只需维护一条 DNS 记录,节点增删在 DNS 层完成,应用配置无需改动。

注意区分两种发现:集群启动时的自我发现(通常用初始集群配置完成)与客户端发现集群,这里讨论的是后者。

配置同步与权限变更通知

etcd 的监听能力还常用于解决分布式环境下的一致性问题。一个典型场景是权限数据同步:在分布式数据库中,权限信息可能被任意一个计算节点修改,其他节点必须及时感知,否则会出现同一用户在 A 节点有权限、在 B 节点没有权限的尴尬情况。

常见实现方式是:修改权限时向 etcd 写入变更通知,所有节点监听该路径,收到通知后重新加载权限数据。这样就把「主动轮询」变成了「事件驱动」,既降低了数据库压力,也缩短了权限生效的延迟。类似的模式也可以用在统计信息更新、配置热加载等场景。

落地时的工程要点

  • etcd 自身要高可用:它成为关键依赖后,本身必须多节点部署,否则会变成新的单点;
  • 区分普通与 TLS 记录:安全要求高的环境应统一使用 TLS,并正确配置证书校验;
  • 设置合理租约:租约过短会因网络抖动误摘节点,过长则故障节点残留时间太久;
  • 控制键空间规模:大量键会带来更高的存储与同步成本,应避免把大对象塞进 etcd;
  • 监控 watch 连接:监听连接断开会导致变更丢失感知,需要断线重连与全量兜底机制。

小结

服务发现的价值不在于技术复杂度,而在于它把「节点在哪里」这个易变信息从应用配置里移了出去。配合事件通知机制,分布式系统可以在节点频繁增减的情况下保持稳定,而不需要人工介入每一次变更。

发现与协调机制
服务注册实例启动写入地址并绑定租约,实例退出后租约到期自动摘除
变更通知客户端监听键路径,节点列表或配置变化时事件驱动更新
客户端发现通过 DNS SRV 记录定位集群,明文与 TLS 场景使用不同记录名
查找顺序先查明文客户端记录,再查 TLS 客户端记录
典型应用权限变更通知、配置热加载、分布式锁与选主