在微服务大行其道的今天,服务的粒度被拆分得非常细,随之而来的是服务数量的迅速增长。在云原生的浪潮中,服务治理更多情况下与容器调度平台结合,共同形成一站式的自动化调度治理平台。
当然无论是否使用基于容器的调度系统,服务治理的原理和范畴都不会发生改变,只是实现方式不同而已。
服务治理主要包括服务发现、负载均衡、限流、熔断、超时、重试、服务追踪等。我们今天要讲的,就是服务发现的内容。
本章主要介绍以下内容:
现在,让我们开始本次的旅程吧。
服务发现指的是寻找一个serviceprovider的网络位置信息。
具体指的是,使用一个注册中心来记录分布式系统中全部服务的信息,以便让其他服务能够快速找到这些已经注册的服务。
服务发现是支撑大规模SOA和微服务架构的核心模块,需要具有服务注册、服务查找、服务健康检查和服务变更通知等关键功能。
因为没有服务发现模块的话,服务网络位置信息的配置会耦合在具体服务消费者的配置当中,从而导致系统难以维护。
想想这么一个基本的问题:服务消费者们是如何知道服务提供者的IP和端口的呢?
在简单的体系架构中,静态配置(比如DNS、Nignx负载均衡配置等)的方法可以很好的解决问题。每个服务都部署在同一个位置,并且很少更改。没有弹性伸缩的需求。传统的单体式应用的网络地址发生变化的概率较小,在发生变化的时候,运维人员手动更新、加载配置文件即可。
但是在微服务架构中并非如此,微服务更新、发布频繁,并且经常会根据负载情况进行弹性伸缩,因为微服务应用实例的网络地址变化是一个很常态的事情,而我们前面提到的静态配置的解决方案,显然不适合这么一个高度动态的场景。所以,我们需要提供一种机制(模块),让服务消费者在服务提供者的IP地址发生变化的时候能够快速及时地获取到最新的服务信息。
前面说过,使用一个注册中心来记录分布式系统中全部服务的信息,以便让其他服务能够快速找到这些已经注册的服务。
让我们用两个例子来说明服务发现运作的机制(简单版本):
当bizservice采用集群架构,有更多的节点上线时,整个工作流是怎么样的呢?
虽然“服务发现”的整个运行机制理解起来很简单,但是在实际的分布式场景下,作为微服务架构体系的一个核心,我们肯定需要采用搭建集群的方式,保证其高可用性。这时候,就需要考虑一个分布式系统可能会遇到的一些问题。
在一个分布式的计算机系统中,只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)这三个基本特性中的两个,这就是著名的CAP定理。
对于分布式系统来说,分区容错性是必须满足的。因此,必须要在一致性和可用性之间进行取舍,这就是所谓的“选择AP还是选择CP”。
对于服务发现和注册中心集群来说,如果选择一致性而牺牲可用性(选择CP)的话,那么为了保证多点服务中心上的数据一致,一旦某个点的服务中心宕机,服务中心集群都需要暂停对外提供数据写入服务。在保证服务中心集群的数据一致的同时,牺牲了写入服务的可用性。如果选择可用性而牺牲一致性(选择AP)的话,那么为了保证服务不中断,当某个点的服务中心宕机时,仍然存活的服务中心节点可以选择先将数据写入本地存储然后直接返回客户端,但这样又将导致多个节点之间的数据不一致。
业界提供的用于服务发现注册的系统,本质上都是满足AP或CP的系统。
在分布式服务体系中,所有的服务提供者和消费者都依赖于【服务中心】,如果服务中心出现问题,将会出现服务状态感知不敏感等现象,且波及整个系统。因此,保证用于服务发现的注册中心的可用性至关重要。为保证注册中心的可用性,要保证多节点部署,如果是大型网站后台通常还要跨多机房进行部署,以确保注册中心在单一机房不可用的情况下仍然可以提供服务。具有高可用特性的服务中心需要具备以下几个能力:
在下面的章节中,我们将介绍几个常见的可直接作为注册中心的产品。
Zookeeper致力于提供一个高可用且具有严格顺序访问控制能力的分布式协调系统,它是一个分布式数据一致性的解决方案。
ZooKeeper提供了分布式通知和协调、配置管理、命名服务、主节点选举、分布式锁、分布式队列等完善的解决方案。其中分布式通知和协调被广泛用于服务发现。至今为止,它是服务发现领域历史最为悠久、使用最为广泛的产品。
Zookeeper的读写机制和一致性协议决定了它是一个CP系统。
ZooKeeper作为使用最为广泛的分布式协调组件,优点非常多。使用广泛就是它最大的优点,这也使得ZooKeeper很容易在架构师进行技术选型时占据优势。但是,需要明确说明的是,Zookeeper并不是服务发现领域的最佳选择了,它的优势主要体现在选举和分布式锁等分布式强一致性的场景中。当ZooKeeper的主节点因为网络故障与其他节点失去联系而触发整个系统选举时,集群是不可用的,这将导致注册服务体系在选举期间瘫痪。
服务中心对数据一致性的要求并不是非常苛刻的,也难于做到实时感知宕机(会有时延),它更看重的是自愈能力。通过Zookeeper的客户端Curator的缓存能力能够让ZooKeeper在服务发现领域的适配度更高,但这并非ZooKeeper的原生能力和设计初衷。
随着CoreOS和Kubernetes等项目在开源社区日益火热,它们项目中都用到的etcd组件作为一个高可用、强一致性的服务发现存储仓库,渐渐走进开发人员的视野。
相比Zookeeper,etcd还具有以下优点:
Eureka比ZooKeeper这类的CP系统更加适合作为服务发现体系中的注册中心。Eureka优先保证了可用性,它采用了去中心化的设计理念,整个服务集群由对等节点组成,无须像ZooKeeper那样选举主节点。集群中失效的节点不会影响正常节点对外提供服务注册和服务查询能力。Eureka客户端有失效转移的能力,如果在向某个Eureka服务器注册服务时发现连接失败,则会自动切换至其他节点。因此,只要有一台Eureka服务器节点还能够正常工作,就无须担心注册中心的可用性。但是,保证可用性必然造成数据一致性的缺失,客户端查询到的信息不一定是最新的。
Consul使用Go语言编写,因此具有天然可移植性(支持Linux、windows和MacOSX);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合。
和etcd一样,Consul基于raft协议,要求必须过半数的节点都写入成功才认为注册成功Leader挂掉时,重新选举期间整个Consul不可用。保证了强一致性但牺牲了可用性。
Nacos是我们国内阿里巴巴的新开源项目,其核心定位是“一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台”。(通俗的理解就是,注册中心+配置中心)
服务(Service)是Nacos世界的一等公民。Nacos支持几乎所有主流类型的“服务”的发现、配置和管理: