title

date

comments

categories

tags

permalink

开源服务注册中心如何选型

2020/5/20

true

8.15

微服务

当下主流的服务注册与发现的解决方案,主要有两种:

  • 应用内注册与发现:注册中心提供服务端和客户端的 SDK,业务应用通过引入注册中心提供的 SDK,通过 SDK 与注册中心交互,来实现服务的注册和发现。
  • 应用外注册与发现:业务应用本身不需要通过 SDK 与注册中心打交道,而是通过其他方式与注册中心交互,间接完成服务注册与发现。

两种典型注册中心的实现方式

应用内

采用应用内注册与发现的方式,最典型的案例要属 Netflix 开源的 Eureka,官方架构图如下。

什么时候 用注册中心 cp 和ap 注册中心选择_什么时候 用注册中心 cp 和ap

从图中可以看出,她主要由三个重要的组件组成

  • Eureka Server:注册中心的服务端,实现了服务信息注册,存储以及查询等功能
  • 服务端的Eureka Client:集成在服务端的注册中心SDK,服务提供者通过调用SDK,实现服务的注册和反注册等功能
  • 客户端的Eureka Cline:集成在客户端的注册中心SDK,服务消费者通过调用SDK,实现服务的订阅和更新等功能
应用外

采用应用外方式实现服务注册和发现,最典型的案例是开源注册中心 Consul,它的架构图如下。(在前面的一节,已经实际动手操作过consul了,只有这样才能真正掌握)。

什么时候 用注册中心 cp 和ap 注册中心选择_服务端_02

从图中可以看出consul也是由三个重要组件组成

  • Consul: 注册中心的服务端,实现服务注册信息的存储,并提供注册和发现服务
  • Registrator: 一个开源的第三方服务管理项目,它通过监听服务器部署的Docker实例是否存活,来负责服务提供的注册和销毁。
  • Consul Template: 定时从注册中心服务端获取最新的服务提供者节点列表并刷新LB配置,比如Nginx的upstream,这样服务消费者就通过访问Nginx获取最新的服务提供者信息。

这两种解决方案的不同之处在于应用场景,应用内的解决方案一般适用于服务提供者和服务消费者同属于一个技术体系;应用外的解决方案一般适合服务提供者和服务消费者采用了不同技术体系的业务场景,比如服务提供者提供的是 C++ 服务,而服务消费者是一个 Java 应用,这时候采用应用外的解决方案就不依赖于具体一个技术体系。同时,对于容器化后的云应用来说,一般不适合采用应用内 SDK 的解决方案,因为这样会侵入业务,而应用外的解决方案正好能够解决这个问题。

注册中心选型要考虑的两个问题

在选择注册中心方案的时候,除了要考虑是采用应用内注册还是应用外注册的方式以外,还有两个最值得关注的问题,一个是高可用性,一个是数据一致性。

  1. 高可用性

注册中心作为服务提供者和消费者之间沟通的纽带,它的高可用性十分重要。如果注册中心挂了,那么两边都不能正常运行了。

实现高可用的方法主要有两种

  • 集群部署,保证即使有部分服务器宕机,也有备用机器顶上去
  • 多IDC部署,就是部署多个机房,这样就算一个机房因为断电或者挖断光缆等不可抗因素而无法运作的时候,依然可以把服务前移到其他机房来保证正常访问。

以Consul为例,来看看它是如何通过这两种方法来保证注册中心的高可用的

什么时候 用注册中心 cp 和ap 注册中心选择_服务提供者_03

从上图可以看到,一方面,在每个数据中心内有多个注册中心Server节点可供访问;另一方面还可以部署在多个数据中心来保证多机房高可用性。 2. 数据一致性

高可用性就需要部署多台主机,不管是集群还是IDC,提供服务的主机的数据一致性就会成为一个问题。在从0开始学架构篇中,已经介绍过CAP理论,也就是高可用、一致性、分区容错性,这三者是不可能三角。此处不再赘述。

为了解决数据一致性,也大致有两种解决方式

  • CP 型注册中心,牺牲可用性来保证数据强一致性,最典型的例子就是 ZooKeeper,etcd,Consul 了。ZooKeeper 集群内只有一个 Leader,而且在 Leader 无法使用的时候通过 Paxos 算法选举出一个新的 Leader。这个 Leader 的目的就是保证写信息的时候只向这个 Leader 写入,Leader 会同步信息到 Followers,这个过程就可以保证数据的强一致性。但如果多个 ZooKeeper 之间网络出现问题,造成出现多个 Leader,发生脑裂的话,注册中心就不可用了。而 etcd 和 Consul 集群内都是通过 raft 协议来保证强一致性,如果出现脑裂的话, 注册中心也不可用。
  • AP 型注册中心,牺牲一致性来保证可用性,最典型的例子就是 Eureka 了。对比下 Zookeeper,Eureka 不用选举一个 Leader,每个 Eureka 服务器单独保存服务注册地址,因此有可能出现数据信息不一致的情况。但是当网络出现问题的时候,每台服务器都可以完成独立的服务。

而对于注册中心来说,最主要的功能是服务的注册和发现,在网络出现问题的时候,可用性的需求要远远高于数据一致性。即使因为数据不一致,注册中心内引入了不可用的服务节点,也可以通过其他措施来避免,比如客户端的快速失败机制等,只要实现最终一致性,对于注册中心来说就足够了。因此,选择 AP 型注册中心,一般更加合适。

总结

  • 如果你的业务体系都采用 Java 语言的话,Netflix 开源的 Eureka 是一个不错的选择,并且它作为服务注册与发现解决方案,能够最大程度的保证可用性,即使出现了网络问题导致不同节点间数据不一致,你仍然能够访问 Eureka 获取数据。
  • 如果你的业务体系语言比较复杂,Eureka 也提供了 Sidecar 的解决方案;也可以考虑使用 Consul,它支持了多种语言接入,包括 Go、Python、PHP、Scala、Java,Erlang、Ruby、Node.js、.NET、Perl 等。
  • 如果你的业务已经是云原生的应用,可以考虑使用 Consul,搭配 Registrator 和 Consul Template 来实现应用外的服务注册与发现。