3.4 服务发现:定位每个跳动的器官


3.4 服务发现:定位每个跳动的器官

摘要:服务一多且老变(扩容、宕机、升级、缩容),它的地址就不再是写死在配置文件里的固定值。服务发现解决"该找谁、它在哪、还活着吗"三个问题。本文讲通注册中心 + 心跳、客户端发现与服务端发现两种模式,以及注册中心自己挂了怎么办。

网关知道要调"订单服务",但订单服务现在有几个实例?132.168.1.7 还是 .12?地址是不是刚因为扩容换过了?如果把这些写死进配置文件,那你每次扩缩容都要改配置、重启、多版本并存——这在几十个服务的世界里就是一场灾难。服务发现就是为"地址漂移"而生的。

先从最直观的问题看起

没有服务发现时,你是这样调服务的:

# 每个环境都要维护一份"谁在哪"的地图,改了配置就得重启 ORDER_SERVICE_1=http://10.0.3.14:8080 ORDER_SERVICE_2=http://10.0.3.15:8080

一旦加一台实例、宕一台机器、升级一次,这份 map 就过期了。服务发现把这件事自动化:服务起来时自己报个到,挂掉时自动注销,调用方随时问注册中心"现在谁还活着"

三步走的机制:注册、心跳、发现

典型流程如下:

三件事分别回答三个问题:

  • 注册:服务启动时把"我叫什么、我在哪、我有什么端口"登记到注册中心。
  • 心跳:服务周期上报"我还活着";注册中心若在一段时间内没收到,就把该实例移出可用列表。
  • 发现:调用方查"我要的服务现在有哪些存活的实例",拿列表自行负载均衡,或者由网关/注册中心代理转发。

两种模式,一条分界线

服务发现有个经典分叉:发现逻辑放在那边。

  • 客户端发现(Client-side Discovery):调用方自己去注册中心查服务列表,自己挑一个实例发请求。实现直接,但每个服务都要集成发现逻辑,且直接依赖注册中心。
  • 服务端发现(Server-side Discovery):调用方只发请求给一个"负载均衡器",由均衡器查注册中心并转发到具体实例。客户端很薄,逻辑集中在服务端(典型如 Kubernetes 里的 Service + DNS + 负载均衡,配合我们第 5 章要讲的 k8s,这条路最省心)。

用一张表对比:

模式 谁去查 优点 缺点
客户端发现 调用方 实现直接、无中间跳 每个服务都要写发现逻辑,依赖注册中心
服务端发现 负载均衡器/平台 客户端薄、运维集中 多了均衡器一层,配置稍复杂

实际趟过水的团队大多会告诉你:能用平台自带的服务发现(比如 k8s 的 Service)就别自己造一个 Galera 全家桶。自己造注册中心+发现框架,是很多团队当年最痛的弯路之一——不是不会,而是维护成本远超想象。

注册中心自己挂了怎么办

服务发现把所有地址都系在一个注册中心上,它自己挂了岂不是全崩?这里要说透:注册发现机制是"易失的、可牺牲的",真正不能牺牲的是你的调用链路。应对三板斧:

  1. 调用方本地缓存:查过一次就缓存地址列表,注册中心临时抖动时用缓存继续跑,不打断业务。
  2. 注册中心高可用:多副本部署(注意节点间的选主与一致性),用我们熟知的分布式一致性手段兜底。
  3. 降级不用它也能跑:极端情况下退回配置文件/静态列表,宁可略微过期也不让整站断流。

这本质上是在说:服务发现的设计目标不是"永不故障",而是"故障时把它对业务的影响压到最小"。这一思想在第 6 章弹性容错里会被正式升格成原则。

一个小小的现实观察:注册中心 ≠ 永远新鲜

注册中心和真实状态之间必然有一点滞后:刚宕的实例还在列表上、刚起的实例还没被看到。这不是 bug,是分布式系统的固有代价。所以调用方要有"调过去发现连不上了就换下一个实例"的容错,而不能拿"注册中心说了算"当护身符。这里又接回第 6 章要讲的重试和熔断。

陷阱:把注册中心当成"唯一真相"

最常见的错,是把注册中心的地址列表当成"一切以它为准"的圣旨,连自己的本地缓存都不敢置信。结果注册中心抖一下,全站跟着哆嗦。正确的心态是:注册中心提供一个近期的、经常对的提示,真正的存活状态要靠调用时的探活来兜底。两套信息互相校验,才稳。

别忘了"健康检查"和"存活性"不是一回事

服务发现里最容易糊弄过去的细节,是把一个服务"还活着"当成"能干活"。心跳证明的只是进程心跳在跳、端口还开着——可一个端口开着的服务,完全可能因为数据库连接满、缓存失效、线程池卡死而"活而无效"。这就是为什么越来越多平台把探活分成两档:liveness(我还活着吗,死了就重启)readiness(我能接流量吗,暂时接不了就摘除法补)。前者管进程生死,后者管对外准入。

这两档分开的价值很具体:如果一个服务因为"临时欠了资源"而暂时接不了流量,平台应该把它从可用列表摘下来、让调用方再缓冲一瞬,而不是立刻把它当坏的杀掉反复重启。把"存活"和"就绪"分开管,是在服务发现之上又加了一层真实的业务可用性判断——这也是很多系统"注册中心没问题、但请求照样超时"时真正差的那一环。

本节要点

  • 一句话:服务发现的价值,是让"地址该变了"和"谁还活着"自动化,别让你手动设

  • 服务发现解决"该找谁、在哪、还活着吗",应对地址漂移

  • 三件套是注册 + 心跳 + 发现:起来报名、定期报活、查询列表

  • 客户端发现自研实现更直,服务端发现运维更集中(k8s Service 最省心)

  • 注册中心可牺牲,本地缓存 + 探活兜底保证调用链路不断

  • 别把注册中心当唯一真相,状态滞后是常态,靠调用容错补齐


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U