今天这篇,我们主要讲解微服务架构中,为什么需要服务发现,服务发现是什么,服务发现中有哪些重要角色,又有哪些具体发现模式供我们应用实践。
为什么需要服务发现
微服务架构下服务实例具有动态分配的网络地址,随着服务的自动扩展、故障和发布升级,导致服务实例的网络地址发生动态变更。
因此,需要一种机制,支持服务消费者在服务提供者实例地址发生变更时,能够及时感知获取实例最新的地址,即服务发现机制。
什么是服务发现
服务发现的概念是随着计算机体系结构的发展而演变的旧概念。随着互联网的发展,主机的增加速度越来越快,需要一个自动化,可扩展性的更强系统,从而导致了DNS的发明和广泛采用。
现在,微服务架构正在推动服务发现的不断发展。随着容器化平台或云平台的不断普及,基于平台的微服务架构部署,服务的生命周期以秒和分钟来衡量。
同时,因为微服务的自动扩展、故障和发布升级,导致微服务具有动态变化的地址列表,微服务的灵活性再次推动了服务发现技术的发展。现代基于容器化平台或云平台的微服务应用程序,需要解决服务地址动态变化的问题。
服务实例的地址动态变化,对于客户端而言,手工维护服务实例地址列表的方式已经不能满足需求,而使用服务发现模式动态更新维护服务实例地址列表是目前微服务架构下使用的必备技术。
服务发现的三个主要角色
目前微服务的服务发现机制主要包含三个角色:服务提供者、服务消费者和服务注册表
- 服务提供者(Service Provider):服务启动时将服务信息注册到服务注册表,服务退出时将服务注册表的服务信息删除掉。
- 服务消费者(Service Consumer):从服务注册表获取服务提供者的最新网络位置等服务信息,维护与服务提供者之间的通信。
- 服务注册表(Service Registry):联系服务提供者和服务消费者的桥梁,维护服务提供者的最新网络位置等服务信息。
服务发现机制的关键部分是服务注册表(Service Registry)。服务注册表提供管理和查询服务注册信息的API。当服务提供者的实例发生变更时(新增/删除服务),服务注册表需要通知服务消费者同步最新的服务实例地址列表。
目前大多数的微服务框架使用Netflix Eureka、Etcd、Consul或Apache Zookeeper等作为服务注册表。
微服务的服务发现模式
微服务有两种主要的服务发现模式:客户端发现模式和服务端发现模式。
客户端发现模式
使用客户端发现模式,客户端负责确定服务提供者的可用实例地址列表和负载均衡策略。客户端访问服务注册表,定时同步目标服服务发现的关键部分是服务注册表。
服务注册表提供管理和查询服务注册信息的API。可以使用Netflix Eureka、etcd、Consul或Apache ZooKeeper等服务注册表搭建服务发现基础设施。
上图所示客户端服务发现包含自注册和客户端发现两个部分:
- 自注册:服务实例调用服务注册表的注册接口进行实例地址注册。服务实例还可以提供服务运行状况检查接口,服务注册表定期访问接口检查服务实例是否健康和处理请求。服务注册表可能要求服务实例定期调用“心跳”API以防止服务实例注册过期。
- 客户端发现:当服务客户端调用目标服务时,它会查询服务注册表以获取服务实例地址列表。为了提高性能,客户端缓存服务实例地址列表。然后,服务客户端使用负载均衡算法(如循环或随机)来选择服务实例发送请求。
我们常用的客户端服务发现模式可以这样实现。用Etcd作为服务注册表,它是一个强一致性键值数据存储的分布式系统,它提供了REST APIs,用于管理服务实例注册和查询服务实例地址列表。
MSF SDK作为微服务SDK,它提供了服务注册功能,支持定期续租服务注册信息。它提供了服务发现功能,访问服务注册表同步并缓存目标服务的实例地址列表,支持基于负载均衡策略选择可用的目标服务并发送请求。
优点:
- 通常是服务客户端查询目标服务的实例地址列表之后,执行负载均衡算法选择可用的目标服务。优点是服务客户端可以灵活、智能地制定负载均衡策略,包括轮询、加权轮询、一致性哈希等策略。
- 可以实现点对点的网状通讯,即去中心化的通讯。可以有效避开单点造成的性能瓶颈和可靠性下降等问题。
- 服务客户端通常以SDK的方式直接引入到项目,这种方式语言的整合程度最佳,程序执行性能最佳,程序错误排查更加容易。
缺点:
- 服务客户端与服务注册表耦合。需要为服务客户端使用的每种编程语言和框架实现客户端服务发现逻辑。
- 服务客户端通常以SDK方式使用服务发现功能。这种侵入式方案存在于应用程序的所有客户端,如果客户端服务发现功能需要进行更新,要求所有的应用程序重新编译,部署服务。微服务的规模越大,服务更新越困难,这在一定程度上违背了微服务架构提倡的技术独立性。
服务端发现模式
使用服务端发现模式,服务客户端通过路由器(或者负载均衡器)访问目标服务。路由器负责查询服务注册表,获取目标服务实例的地址列表转发请求。
上图所示服务端服务发现包含第三方注册和服务端发现两个部分:
- 第三方注册:这种方式不是服务客户端向服务注册表注册服务,而是通过一个注册处理器处理服务注册(通常是部署平台的一部分)。
- 服务端发现:这种方式不是服务客户端查询服务注册表,而是发送请求给路由器(或者负载均衡器),路由器查询服务注册表获取目标服务的实例地址列表,使用负载均衡算法(如循环或随机)选择可用的服务实例转发请求。
现代容器化部署平台(如Docker和Kubernetes)就是服务端服务发现模式的一个例子,这些部署平台都具有内置的服务注册表和服务发现机制。容器化部署平台为每个服务提供路由请求的能力。
服务客户端向路由器(或者负载均衡器)发出请求,容器化部署平台自动将请求路由到目标服务一个可用的服务实例。因此,服务注册,服务发现和请求路由完全由容器化部署平台处理。
优点:
- 部署平台提供服务发现功能,负责处理服务发现的所有方面。因此,无论使用任何语言,所有的服务提供者和消费者都可以轻松地使用服务发现机制。
- 服务发现功能对于服务客户端而言是透明的,因此,服务发现功能的相关更新对于服务客户端是无感知的。
缺点:
- 部署平台的服务发现功能仅支持发现使用该平台部署的服务。例如,基于Kubernetes 的服务发现仅适应于在Kubernetes上部署运行的服务。
- 服务的架构增加了一次转发,延迟时间会增加。整个系统增加了一个故障点,系统的运维难度增加。最关键的是负责转发请求的路由器或者负载均衡器可能变成性能的瓶颈。
- 微服务的一个目标是故障隔离,将整个系统切割为多个服务共同运行,如果某服务无法正常运行,只会影响到整个系统的相关部分功能,其它功能能够正常运行,即去中心化。然而,服务端发现模式实际上是集中式的做法,如果路由器或者负载均衡器无法提供服务,那么将导致整个系统瘫痪。