微服务架构 中,服务数量往往成百上千,服务实例还会因为弹性伸缩、故障恢复、滚动升级等频繁上下线。服务发现(Service Discovery) 就是解决“客户端如何知道服务在哪里”的问题。


一、服务发现的作用

  1. 屏蔽服务位置的动态变化
    服务实例的 IP/端口不是固定的,手工配置既不现实也容易出错。服务发现让调用方不必关心服务的具体地址。

  2. 实现负载均衡
    服务发现可以返回一组可用服务实例,调用方通过负载均衡策略(如轮询、权重、最少连接数)选择目标。

  3. 增强系统的弹性与可扩展性
    新服务实例注册后即可被发现并使用;失效实例被摘除,不会影响调用。

  4. 支持故障容错
    调用方能根据发现机制实时感知健康的服务实例,避免请求打到不可用节点。


二、服务发现的设计思想

  1. 注册与查询分离

    • 服务注册(Service Registration):服务启动后向注册中心报告自己的信息(如 IP、端口、元数据),并定期心跳维持。
    • 服务发现(Service Discovery):调用方通过注册中心获取目标服务的实例列表。
  2. 两种发现模式

    • 客户端发现(Client-side Discovery)
      调用方自己从注册中心拉取服务列表,并实现负载均衡。
      ✦ 优点:架构简单,调用方直接控制。
      ✦ 缺点:客户端耦合发现逻辑,升级维护困难。
      ✦ 示例:Eureka、Consul。

    • 服务端发现(Server-side Discovery)
      调用方只发请求到一个负载均衡器(如 API Gateway、Service Mesh Sidecar),由它去注册中心查询并转发。
      ✦ 优点:调用方无感知,逻辑集中。
      ✦ 缺点:对中间件依赖更重,架构复杂。
      ✦ 示例:Kubernetes Service、Istio。

  3. 健康检查机制
    注册中心要定期探测服务实例的存活状态(心跳检测、HTTP 探针、TCP 检测),保证发现结果的正确性。

  4. 一致性与可用性权衡

    • 需要保证服务列表的实时性和一致性,但同时要兼顾高可用。
    • 常见做法是“最终一致性”,即服务上下线信息传播有少许延迟,但系统整体可接受。
  5. 与配置管理和路由策略结合
    服务发现往往结合配置中心、API Gateway、熔断限流策略,构成完整的服务治理体系。


三、典型实现

  • Eureka(Netflix 开源):客户端发现模式,Spring Cloud 经典组件。
  • Consul:支持健康检查、KV 存储,既可客户端发现也能和 Envoy 配合做服务端发现。
  • Zookeeper:早期分布式协调工具,常用于 Dubbo 的服务注册与发现。
  • Kubernetes Service + DNS:通过 kube-dns/CoreDNS 提供服务端发现,Pod 动态变化对外透明。
  • **Istio (Service Mesh)**:通过 Sidecar 代理统一实现服务发现、流量管理、安全控制。

✨一句话总结:
服务发现的核心思想是“解耦调用方与服务实例的物理地址”,让服务调用始终面向逻辑服务名,而由注册中心或代理负责映射到实际运行实例。