在我们服务使用 REST API 调用服务时,是需要知道服务实例的网络位置(IP 地址和端口)。
在服务器上运行的传统应用程序中服务实例的api通常是静态的。在现在基于云的微服务应用程序中,api通常不是那么简单设置。由于自动缩放、故障和升级,服务实例会动态变化。因此,我们必须在客户端代码中使用服务发现。
1、服务发现
服务的IP地址不能在客户端静态配置。需要使用动态服务发现。从概念上讲,服务发现非常简单,它的主要组件是一个服务注册表,它包含一个应用程序服务实例的网络位置列表。
当服务实例启动和停止时,服务注册表会更新。服务发现机制通过查询服务注册表以获取可用服务实例的列表,并在客户端调用服务时将请求路由到其中一个。
2、应用程序级服务发现模式
应用程序的服务及其客户端可以与服务注册中心交互以实现服务发现。每个服务实例向服务注册表注册其网络位置,在调用服务之前从服务注册中心请求服务实例列表。然后,客户端向其中一个实例发送请求。
这种方法是两种模式的组合。
- 自注册模式:在启动期间,服务实例调用注册中心的注册 API 来注册其网络位置,注册中心要求服务实例定期调用心跳 API 以防止其注册过期。当服务实例关闭时,它会从服务注册表中注销自己。
- 客户端发现模式:为了调用服务,服务客户端向服务注册中心查询服务实例列表。客户端使用负载平衡算法来选择服务实例,然后由客户端请求选定的实例。
Netflix 和 Pivotal 已经普及了企业级服务发现。例如,Netflix 的 Eureka 是一个高可用的服务注册中心。Netflix 组件可以很容易地与 Spring Cloud 一起使用,这是一个由 Pivotal 开发的基于 Spring 的框架。基于 Spring Cloud 的服务向 Eureka 注册,基于 Spring Cloud 的客户端使用 Eureka 发现服务。
3、应用层服务发现的缺点
- 需要特定语言的服务发现库。
- 需要运维人员维护设置和管理服务注册表。
- 当服务实例正在运行但不处理请求时,会出现从服务注册中心遗漏注销的可行性。
4、平台提供的服务发现模式
许多部署平台例如 Docker 和 Kubernetes,都内置了服务注册表和服务发现机制。每个服务都分配有一个 DNS 名称、一个虚拟 IP (VIP) 地址和一个解析为 VIP 地址的 DNS 名称。
服务客户端请求 DNS 名称/VIP,部署平台自动将请求路由到可用服务实例。这样服务注册、服务发现、请求路由等全部由部署平台处理。服务注册表跟踪部署平台中已部署服务的 IP 地址。
这种方法是两种模式的组合:
- 第 三 方注册模式:不是服务向服务注册中心注册自己,而是由第三方注册商(通常是部署平台的一部分)进行注册。注册器在启动时向服务注册中心注册服务实例。当实例关闭时,注册器会从服务注册表中取消注册服务实例。
- 服务器端发现模式:它不是客户端查询服务注册表,而是向 DNS 名称发出请求,DNS 名称解析为查询注册表并负载平衡请求的请求路由器。AWS 弹性负载均衡器 (ELB) 是服务器端发现路由器的一个示例。客户端向 ELB 发送 HTTP/TCP 请求,ELB 在一组 EC2 实例之间对流量进行负载平衡。ELB 还充当服务注册表。实例通过 API 调用显式注册到 ELB,或者作为自动扩展组的一部分自动注册。
5、基于平台的服务发现的好处
- 部署平台处理服务发现的所有工作。
- 服务和客户端都不包含任何用于服务发现的代码。
- 服务发现对所有服务和客户端都可用,无论它们是用什么语言编写的。
6、基于平台的服务发现的缺点
- 只能发现已使用该平台部署的服务。