后端架构师必知必会系列:服务注册与发现

作者:禅与计算机程序设计艺术

1.简介

在微服务架构中,服务之间相互调用通信需要依赖一个集中的服务注册中心,这个服务注册中心提供服务的注册和查找功能。服务注册中心是一个中心化、分布式的服务管理系统,能够存储服务的元数据、路由规则、负载均衡信息等,帮助服务调用者快速找到需要调用的服务并建立连接。服务注册中心支持多种编程语言的客户端SDK,方便开发人员通过代码配置调用服务。另外,为了实现服务的自动发现、负载均衡、流量控制和熔断机制,服务注册中心还需要配合其他组件一起工作,比如服务健康检查、消息代理、流控和限流等。

今天,我们将介绍服务注册与发现相关的一些基础知识和核心原理,包括但不限于以下几方面:

  1. 服务注册中心的角色和作用
  2. 最基本的服务注册流程
  3. 服务注册中心的选型与特点
  4. Naming Service 的基本原理
  5. Consul 的服务发现原理
  6. Eureka 的高可用性设计与实现
  7. 服务注册中心常用工具和组件
  8. 服务注册中心相关组件之间的联系和区别
  9. 服务注册中心的性能指标监控和优化

希望本系列文章能给读者带来一定的收获和帮助,更好地理解服务注册与发现的重要性和作用。

2.基本概念术语说明

2.1 服务发现(Service Discovery)

服务发现,英文名称叫做 Service Registry 和 Service Directory,翻译成中文就是服务注册与发现。当我们需要调用远程的服务时,通常都需要知道该服务的IP地址或域名,如果每次调用都手动输入这些信息很麻烦且容易出错,所以就需要一种自动的方法来获取服务地址,而服务发现就是这样一种自动获取服务地址的方法。

2.2 服务注册中心(Service Registration Center/Registry)

服务注册中心是一个分布式的服务管理系统,它存储了服务的元数据、路由规则、负载均衡信息等,并且提供了各种语言的客户端SDK,方便开发人员通过代码配置调用服务。一般情况下,一个集群里只需要有一个服务注册中心就可以了。

2.3 服务名(Service Name)

服务名是用来标识一个具体的服务的唯一名称,由一组字符串组成,形式为"{service_name}[{namespace}].{domain name}",例如"user-service[prod].example.com"。服务名分为两部分,前半部分为服务名,中间可选的命名空间和域名前缀,后半部分为域名前缀。命名空间用于划分环境、业务单元等,方便对不同的环境部署的服务进行隔离,避免它们之间的相互影响;域名前缀则是在同一个私有网络里可以自定义的域名前缀,用于区分不同组织的服务。

2.4 服务治理(Service Governance)

服务治理,即服务的生命周期管理和调优。服务治理,主要目的是保障服务质量,同时也促进系统架构的演进与变革。服务治理包括服务发现、服务路由、服务容量规划、服务降级策略、服务访问授权和审计等。

2.5 服务节点(Service Instance)

服务实例(Instance)是注册到服务注册中心的服务对象,每一个服务节点都会被赋予一个唯一的ID,称之为实例ID(InstanceId),用于标识一个服务节点。服务实例除了包含服务实例ID外,还有一些元数据,如主机IP、端口号、主机名、版本号等。服务实例可以动态加入和退出注册表,从而实现服务的动态注册与注销。

2.6 服务健康状态(Health Check)

健康状态是指某个服务是否正常运行,正常运行意味着服务提供者已经准备好接受请求,正常响应客户端的请求,无异常故障发生等。服务健康状态可以通过系统自身的检测或者调用第三方组件如监控系统来判断,也可以根据服务实例的统计信息和日志信息来判断。

2.7 负载均衡器(Load Balancer)

负载均衡器负责分配每个请求到各个服务实例的过程,是实现服务发现的重要手段。负载均衡器基于某种负载均衡算法,根据服务实例的健康状态、请求处理能力等因素,按照一定规则把请求均匀分配给各个实例。负载均衡器还具备抗攻击能力、流量控制、故障切换能力等功能,提升服务的可用性。目前主流的负载均衡器有轮询(Round Robin)、随机(Random)、加权(Weighted)等。

2.8 服务注册中心的角色和作用

服务注册中心作为微服务架构的一部分,主要承担三个职责:

  1. 服务实例的注册与发现:服务实例启动之后,向服务注册中心发送注册请求,将自己的信息注册到服务注册中心,以便服务消费者可以发现该服务。服务消费者可以在本地缓存注册表的信息,也可以通过远程调用方式获取服务的最新地址。

  2. 服务路由与负载均衡:服务路由指的是服务消费者如何选择访问哪一个服务实例。服务消费者可能会根据当前请求的特征来选择负载较低的实例,降低整体的负载压力。同时,服务注册中心还可以提供负载均衡的功能,即通过某种负载均衡算法,把请求平均分配给多个服务实例。

  3. 服务元数据的存储与查询:服务元数据主要包括服务实例的属性信息,如主机IP、端口号、主机名、版本号、负载均衡策略等。服务注册中心通过索引的方式支持复杂的查询条件,可以根据不同的维度查询服务实例。

2.9 服务注册中心选型与特点

服务注册中心有很多开源产品,但各产品之间的差异比较大,这里推荐几个常用的服务注册中心产品,供读者参考。

  1. Nacos (Nacos: an open source platform for dynamic service discovery and configuration and service management): Nacos 是阿里巴巴开源的基于 Spring Cloud Alibaba 生态圈的动态服务发现和配置管理中心,它提供简单易用的 GUI 界面,使得用户可以直观地查看和管理服务。其主要特点包括:支持跨平台、多语言、丰富的特性、完善的文档、生态丰富的生态系统以及海量的社区支持。

  2. Zookeeper (Apache ZooKeeper): Apache ZooKeeper 是一个分布式协调服务,是一个开源的分布式计算框架,它的主要目标是提供 Distributed Lock 和 Coordination Services。Zookeeper 提供的特性包括:配置维护、同步、通知、集群管理、Master 选举、分布式锁等,适用于基于集群的应用程序。

  3. Etcd (etcd: a distributed reliable key-value store for the most critical data of a distributed system): etcd 是 CoreOS 公司推出的开源项目,它是一个高可用的键值对数据库,用于共享配置和服务发现。Etcd 支持监听、通知机制,因此客户端可以实时地接收服务的变化信息。

选用服务注册中心产品时,需要考虑其优缺点,以及所处的微服务架构的阶段。如果是初创阶段或者刚刚接触微服务架构,推荐使用 Nacos 或 Zookeeper。如果是已有成熟的系统,建议选用 Etcd 。

3. Naming Service 的基本原理

Nacos 是阿里巴巴开源的基于 Spring Cloud Alibaba 生态圈的动态服务发现和配置管理中心,它基于 JVM 实现,支持 Java、Go、C++、Python、PHP、Node.js 等多语言。除此之外,Nacos 还支持 DNS 协议解析服务名,适合在容器环境下使用。下面我们来看一下 Nacos 中 Naming Service 的基本原理。

3.1 Naming Service 的工作原理

Nacos 采用的是 Paxos + 存储的共识算法,来保证服务的一致性。Paxos 算法是一种消息传递算法,其解决的问题是分布式系统中,多个节点之间需要协商一致的问题。Storage 则是一个基于磁盘的持久化存储模块。

Naming Service 在整个 Nacos 中扮演着服务注册中心的角色,所有的服务实例首先向 Naming Service 注册自己的服务,Naming Service 根据服务名生成对应的唯一 ID ,然后将该 ID 以及 IP 地址和端口号等信息存储至本地存储 Storage 中,再通过心跳检测维持服务的存活状态。

当服务消费者想访问某个服务时,需要先向 Naming Service 获取服务名对应的唯一 ID。然后通过该 ID 查找本地存储中相应的服务实例,根据负载均衡策略返回给服务消费者。

上图展示了一个简单的 Naming Service 的架构,其中 Naming Server 负责存储所有的服务实例信息,Client 通过访问 Naming Server 来查询服务实例信息。Client 可以选择不同的负载均衡策略,以实现负载均衡。

3.2 Naming Service 中的关键组件

Nacos 主要包含如下关键组件:

  1. Namespace:命名空间,用于隔离不同环境下的服务,类似 Kubernetes 中的命名空间概念。

  2. Cluster:集群,用于控制注册的服务在哪些机器上可见。

  3. DataId:数据 ID,用于标记不同类型的数据。

  4. Group:集群组,用于对相同服务的不同版本进行分类。

  5. IP:服务 IP,用于记录服务实例的地址。

  6. Port:服务端口,用于记录服务实例的端口。

  7. TTL:时间-to-live,用于控制服务实例的有效期。

  8. Ephemeral:临时实例,用于控制服务实例是否长期存在。

3.3 Naming Service 的优点和局限性

3.3.1 优点

Nacos 有如下优点:

  1. 丰富的特性:Nacos 支持服务级别的流控、降级、容灾等特性,使得运维工作变得更加高效。

  2. 便捷的使用:Nacos 提供了 SDK 和 Web UI 操作界面,用户可以快速地发布和订阅服务。

  3. 强大的扩展性:Nacos 可以通过 SPI 的方式进行插件扩展,支持更多类型的应用场景。

  4. 海量的社区支持:Nacos 具有成千上万的用户群体,并且拥有丰富的技术文章和技术讨论,能够让用户获得及时的帮助。

3.3.2 局限性

Nacos 有如下局限性:

  1. 不支持广播:由于采用 Paxos 算法的特性,导致不能发送全局广播消息。

  2. 并发冲突:Nacos 不是完全的 ACID 模型,容易出现并发冲突的情况。

  3. 没有事务机制:Nacos 虽然支持数据备份和恢复,但是没有提供事务机制,可能造成数据不一致的情况。

  4. 不支持海量数据:Nacos 服务器仅支持少量的元数据,对于海量的服务实例元数据支持不足,无法满足实际需求。

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/133385391