在分布式系统中,为了方便多个服务需要在网络上相互交互,我们需要一种机制使得这些服务能够有效地相互查找和通信,因此,本文我们将探讨一种常见的方案:服务发现。
一、什么是服务发现?
服务发现是一种允许在分布式系统中自动检测和追踪网络中的各个服务实例,它主要解决的问题是服务的动态注册、查找和负载均衡。
二、服务发现的类型
通常来说服务发现有两种主要类型:客户端发现和服务器端发现。
1.客户端发现
在客户端发现中,服务使用者负责查询服务注册表以查找可用的服务实例,然后在这些实例之间对请求进行负载均衡。
优势:易于实施和理解。减少中央负载均衡器上的负载。
缺点:
- 使用者需要实现发现逻辑。
- 注册表协议中的更改需要客户端中的更改。
比如,Netflix Eureka就是一个客户端服务发现的注册中心。
2.服务器端发现
在服务器端发现中,服务使用者向中介(负载均衡器或 API 网关)发出请求,然后中介查询服务注册表并将请求路由到相应的服务实例。
优势:
- 集中发现逻辑,降低使用者的复杂性。
- 更易于管理和更新发现协议。
缺点
- 引入了一个额外的网络跃点。
- 负载均衡器可能成为单点故障。
比如,AWS Elastic Load Balancer(ELB)与 AWS服务注册表集成,以实现服务器端发现。
三、服务发现如何工作?
1.三个组件
服务发现包含三个重要的组件:服务提供者、服务使用者和服务注册表,它们之间的关系如下图:
- 服务提供者(Service Provider):服务提供者在进入系统时向服务注册中心注册,并在离开系统时取消注册。
- 服务使用者(Service Consumer):服务使用者从服务注册表中获取提供者的信息,然后连接到服务提供者。
- 服务注册表(Service Registry):服务注册表是保存服务提供者的相关信息,当服务提供者有变更时,注册表也能感知,以便客户端可以通过从服务注册表获取最新数据。
2.工作原理
- 服务注册:每个服务实例在启动时会向一个服务注册中心(Service Registry)注册自己,包括服务名、实例ID、IP地址、端口号等信息。
- 服务发现:客户端需要访问某个服务时,会先查询服务注册中心以获取可用的服务实例列表,然后选择一个实例进行调用。
- 健康检查:服务注册中心定期对注册的服务实例进行健康检查,确保只有健康的实例在列表中,故障实例会被移除。
- 负载均衡:在客户端从服务注册中心获取服务实例列表后,通常会使用某种负载均衡策略(如轮询、随机、最小连接数等)来选择具体的服务实例进行请求。
四、服务发现的重要性
- 减少手动配置:服务可以动态发现并相互连接,无需手动配置和硬编码网络位置。
- 改进的可扩展性:随着新服务实例的添加或删除,服务发现可确保其他服务能够无缝适应不断变化的环境。
- 增强的容错能力:服务发现机制通常包括运行状况检查,使系统能够自动将流量从失败的服务实例中重新路由出去。
- 简化管理:拥有中央服务注册表可以更轻松地监视、管理和排除整个系统的故障。
五、常用服务发现工具
下面列举了几个分布式环境下常用的服务发现工具。
1.Eureka
Eureka Server采用的是Peer to Peer对等通信,它是一种去中心化的架构,每一个 Peer都是对等的。节点之间通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl指向其他节点。每个节点都可被视为其他节点的副本。,其原理图如下:
Eureka采用的是 ACP理论中的 AP原则,因此,只要 Eureka集群中有一台 Eureka还在,就能保证注册服务可用。
2.Consul
Consul 是一个分布式、高度可用的服务发现和配置系统,它提供服务发现、运行状况检查、键值存储和多数据中心支持,其原理图如下:
Consul采用的是 ACP理论中的 CP模型,使用 Raft算法来保证强一致性,支持多数据中心,可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等。
3.etcd + kubernetes
etcd 是一个分布式键值存储,可用于服务发现和配置管理,其原理图如下:
etcd 是一种高度一致的分布式键值存储,它提供了一种可靠的方法来存储分布式系统或机器集群需要访问的数据。它可以在网络分区期间优雅地处理领导者选举,并且可以容忍机器故障,即使在领导者节点中也是如此。
Kubernetes 是一个容器编排平台,具有内置的服务发现机制。它使用标签和注释来管理服务实例,并通过 DNS提供服务发现。
4.Nacos
Nacos是阿里开源的,支持基于 DNS和基于 RPC的服务发现,它即支持 CP模式也支持 AP模式,可以通过命令的方式切换,其原理图如下:
五、总结
本文,我们分析了什么是服务发现以及它在分布式系统中是如何工作的?对于服务发现我们需要掌握其核心模型:
- 服务提供者(Service Provider):服务提供者在进入系统时向服务注册中心注册,并在离开系统时取消注册。
- 服务使用者(Service Consumer):服务使用者从服务注册表中获取提供者的信息,然后连接到服务提供者。
- 服务注册表(Service Registry):服务注册表是保存服务提供者的相关信息,当服务提供者有变更时,注册表也能感知,以便客户端可以通过从服务注册表获取最新数据。
最后,我们通过分析几个常见的服务发现工具,尽管它们的实现细节略有差异,但是它们的核心模型是一样的,只要能抓住核心模型,即便出现新的框架或者工具,我们也可以快速上手。