一个写死在配置里的 IP
订单服务调库存服务,地址写在配置文件里。上容器之前这个法子凑合能用,上了容器就讲不通了——库存服务今天两台、大促扩到二十台、节点漂移换 IP 是常态。写死地址的调用方:扩容时它不知道,缩容时它还在打,实例下线时它对着连接拒绝干瞪眼。实例会动的世界里,地址必须动态解析——这就是服务注册与发现要解决的问题。
基本盘:注册、心跳、订阅、推送
机制不复杂,四件事串起来:注册——服务启动时把名字、地址、元数据报到注册中心;心跳——定期续约证明自己活着,超时未续约被剔除;订阅——调用方按服务名订阅,拿到实例列表缓存在本地;变更推送——实例增减时,注册中心把新列表推给订阅方。之后的所有调用都发生在调用方与实例之间,注册中心不在调用路径上。
// 一次完整的服务发现
1. inventory 启动,注册:name=inventory, addr=10.2.3.15:8080
2. 每 5s 心跳续约;15s 未续约 -> 标记不健康;30s -> 剔除
3. order 启动,订阅 inventory -> 拿到实例列表并缓存本地
4. 实例增减 -> 注册中心推送变更,order 更新本地列表
5. 之后每次调用:order 从本地列表负载均衡选一台直连CAP:注册中心的分水岭
分布式系统绕不开 CAP:网络分区发生时,一致性与可用性只能保一个。ZooKeeper、Consul 是 CP:分区时为了保证一致会拒绝部分请求,调用方可能拿不到列表。Eureka、Nacos(AP 模式)是 AP:分区时继续返回可能过期的列表——列表旧一点,但调用方有得用。
服务发现这个场景,绝大多数业务应该选 AP:对一个刚下线的实例失败几次,调用方有重试和摘除兜底;拿不到列表,全站一起瘫痪。不少团队用 ZK 做注册中心,分区时"宁要一致不要可用"的特性反而成了故障放大器——这个坑值得绕开。
| 注册中心 | 一致性 | 健康检查 | 一句话点评 |
|---|---|---|---|
| ZooKeeper | CP | 会话保持 | 强一致但分区时不可用,非为发现而生 |
| Eureka | AP | 客户端心跳 | 自我保护机制经典,2.x 已停更 |
| Consul | CP | 多种探测 | K8s 生态友好,多数据中心强 |
| Nacos | AP/CP 可切 | 心跳+主动探测 | 国内主流,注册配置一体化 |
健康检查的两种姿势
剔除坏实例靠两套机制配合:客户端心跳——实例自己定期报平安,实现简单,但进程假死时心跳可能还在跳;服务端探测——注册中心主动发 TCP 或 HTTP 探测,更真实,但探测本身有成本。Nacos 对临时实例用心跳、对持久实例用探测,两类实例的行为差异,下一篇结合 Nacos 的参数细讲。
注册中心选型定了,怎么用对才是重点——下一篇把 Nacos 的注册、上下线与保护阈值这些实战参数一个个过一遍。
评论 (0)