一句话定义:服务发现(Service Discovery)是指服务实例启动时自动把自己的地址登记到公共注册表,调用方发请求前先去注册表查“你现在在哪”,使调用关系不再依赖写死的配置文件。
为什么要这么麻烦:十年前部署一个订单服务,运维知道它运行在哪台机器上,把 10.0.0.7:8080 写进上游服务的配置文件就行。现在容器一调度、实例一扩缩容、机器一故障迁移,IP 和端口随时在变,昨天写死的地址今天就是一堆连不上的死胡同。服务发现就是为了解决“地址是流动的”这个前提。
运作方式:以餐厅通讯录为例,旧办法是印一本纸质通讯录,店一搬家整本作废;服务发现相当于地图 App:每家店自己上报位置并定时更新,顾客每次导航前现查最新坐标。三个角色:服务提供者(Provider)启动时向注册中心(Registry)注册,并定期发送心跳(heartbeat)表示自己在运行;注册中心做健康检查(health check),连续几次没心跳就把该实例摘掉;服务消费者(Consumer)按服务名而不是 IP 去查询,拿到一份当前可用实例列表。
查询有两种风格:客户端发现(client-side discovery),调用方自己拿列表、自己挑一个,通常配合负载均衡策略;服务端发现(server-side discovery),调用方只访问固定入口,由网关或负载均衡器查表后转发。DNS 是最古老的服务发现形式,只是它的“变更生效速度”和健康感知通常不够快。
| 方式 | 地址来源 | 实例更换后 | 典型问题 |
|---|---|---|---|
| 写死配置 | 人工维护 | 需要改配置并重启 | 忘记改、改漏 |
| DNS | 域名解析 | 取决于缓存与 TTL | 摘除坏实例不及时 |
| 注册中心 | 实例自注册与心跳 | 自动跟上 | 注册中心自身要高可用 |
和邻近概念的区别:服务发现回答“有哪些地址可选”,负载均衡(Load Balancing)回答“这次具体选哪个”;两者常一起使用但不是一回事。API 网关(API Gateway)是流量入口,它转发时同样要查询后端地址,也要依赖服务发现。
实际意义:对从业者,滚动发布、弹性扩容、故障实例自动摘除、灰度分流都建立在它之上;排查“服务明明启动了却调不通”时,第一步常去看注册表里到底有没有这个实例、健康状态是什么。对普通人,这意味着高峰期扩容出的新机器能立刻分担流量,某台机器故障时你的请求不会被继续发到一个已经停止运行的地址。注意两点:注册中心自己不能是单点;查到地址不等于一定连通,仍需超时、重试、熔断配合。主流注册中心(Consul、etcd、Nacos、Kubernetes 内置服务等)的能力与配置细节,以官方文档为准。
