服务发现:Zookeeper vs etcd vs Consul

我们拥有的服务越多,如果我们使用预定义的端口,发生冲突的机会就越大。 毕竟,不可能有两个服务在同一端口上侦听。 假设管理数百个服务使用的所有端口的详细清单本身就是一个挑战。 将那些服务需要的数据库添加到该列表中,并且数量还会增加。 因此,我们应该在不指定端口的情况下部署服务,并让Docker为我们分配一个随机端口。 唯一的问题是,我们需要发现端口号并让其他人知道。

服务发现:Zookeeper vs etcd vs Consul

当我们开始在将分布式服务部署到多个服务器之一中的分布式系统上工作时,事情变得更加复杂。 我们可以选择预先定义将哪个服务转到哪个服务器,但这会导致很多问题。 我们应该尽力利用服务器资源,如果我们事先定义将每个服务部署在何处,这几乎是不可能的。 另一个问题是,自动扩展服务充其量是困难的,更不用说从服务器故障中自动恢复了。 另一方面,如果我们将服务部署到运行最少容器的服务器上,则需要将IP添加到需要发现并存储在某处的数据列表中。

服务发现:Zookeeper vs etcd vs Consul

在需要存储和检索(发现)与我们正在使用的服务相关的某些信息的情况下,还有许多其他示例。

为了能够找到我们的服务,我们至少需要以下两个过程可供我们使用。

  • 服务注册过程将至少存储正在运行的主机和端口服务。
  • 服务发现过程,使其他人能够发现我们在注册过程中存储的信息。

除了这些过程之外,我们还需要考虑其他几个方面。 如果服务停止运行并部署/注册新实例,我们应该注销该服务吗? 如果同一服务有多个副本,会发生什么? 我们如何平衡其中的负载? 如果服务器出现故障会怎样? 这些和许多其他问题与注册和发现过程紧密相关。 现在,我们将范围仅限制于服务发现 (包含上述两个过程的通用名称)和我们可能用于此任务的工具。 它们中的大多数功能都具有某种高度可用的分布式键/值存储。

服务发现工具

服务发现工具的主要目的是帮助服务发现彼此并与之交谈。 为了履行职责,他们需要知道每种服务的位置。 这个概念并不是什么新鲜事物,并且在Docker诞生之前很久就存在许多工具。 但是,容器使对此类工具的需求达到了全新的水平。

服务发现背后的基本思想是使服务(或应用程序)的每个新实例能够识别其当前环境并存储该信息。 存储本身通常在注册表中以键/值格式执行。 由于发现通常在分布式系统中使用,因此注册表需要具有可伸缩性,容错能力,并且需要在群集的所有节点之间分布。 这种存储的主要用途是至少向可能需要与其通信的所有相关方提供服务的IP和端口。 该数据通常与其他类型的信息一起扩展。

发现工具倾向于提供某种API,服务可以使用该API进行自身注册,其他人也可以使用该API查找有关该服务的信息。

假设我们有两项服务。 一个是提供者,另一个是其消费者。 部署提供程序后,我们需要将其信息存储到所选的服务发现注册表中。 稍后,当使用者尝试访问提供程序时,它将首先查询注册表,并使用从注册表获得的IP和端口来调用提供程序。 为了使提供程序与注册表的特定实现脱钩,我们经常采用某种代理服务 这样,消费者将始终从位于代理服务器内的固定地址中请求信息,该地址继而将使用发现服务来查找提供者信息并重定向请求。 稍后我们将在本书中介绍反向代理 目前,重要的是要了解基于三个参与者的流程。 消费者,代理和提供者。

我们在服务发现工具中寻找的是数据。 至少,我们应该能够找到服务的位置,它是否健康,可用以及其配置是什么。 由于我们正在构建具有多台服务器的分布式系统,因此该工具必须具有鲁棒性,并且一个节点的故障不应危害数据。 同样,每个节点都应具有完全相同的数据副本。 进一步,我们希望能够以任何顺序启动服务,能够销毁它们或将它们替换为较新的版本。 我们还应该能够重新配置我们的服务,并查看相应的数据更改。

让我们看一下实现我们设定的目标的几种常用选项。

手动配置

大多数服务仍是手动管理的。 我们会预先决定在何处部署服务,它的配置是什么,并希望它能继续正常运行直至结束。 这种方法不容易扩展。 部署服务的第二个实例意味着我们需要重新开始手动过程。 我们需要启动一台新服务器,或者找出哪个服务器的资源利用率较低,创建一组新的配置并进行部署。 假设发生硬件故障,情况甚至更加复杂,因为在手动管理事物时,反应时间通常很慢。 可见性是另一个痛苦的地方。 我们知道什么是静态配置。 毕竟,我们已经提前准备好了。 但是,大多数服务都有大量动态生成的信息。 该信息不容易看到。 当我们需要这些数据时,没有可以咨询的位置。

反应时间不可避免地会很慢,故障恢复力充其量是可疑的,并且由于许多手动处理的运动部件而导致监控难以管理。

尽管过去有手动为这项工作提供借口,或者当服务和/或服务器数量很少时,随着服务发现工具的出现,这种借口Swift消失了。

动物园管理员

ZooKeeper是此类最古老的项目之一。 它起源于Hadoop世界,旨在帮助维护Hadoop集群中的各个组件。 它已经成熟,可靠并且被许多大公司(YouTube,eBay,Yahoo等)使用。 它存储的数据格式类似于文件系统的组织。 如果在服务器群集上运行,Zookeper将在所有节点之间共享配置状态。 每个集群都选出一个领导者,客户端可以连接到任何服务器以检索数据。

Zookeeper带来的主要优势是它的成熟度,健壮性和功能丰富性。 但是,它也有其自身的一系列缺点,其中Java和复杂性是主要原因。 尽管Java在许多用例中都很出色,但对于这类工作却非常繁重。 Zookeeper对Java的使用以及相当数量的依赖关系使它比同等竞争产品消耗更多的资源。 除了这些问题外,Zookeeper也很复杂。 维护它需要的知识比我们从此类应用程序中所期望的要多得多。 这是功能丰富性将自身从优势转换为责任的部分。 应用程序具有的功能越多,我们不需要所有功能的机会就越大。 因此,我们最终以复杂的形式为我们不完全需要的东西付出了代价。

Zookeeper为其他人的改进铺平了道路。 “大玩家”之所以使用它,是因为当时没有更好的选择。 今天,Zookeeper可以显示它的年龄,而其他选择使我们变得更好。

etcd是可通过HTTP访问的键/值存储。 它是分布式的,具有可用于构建服务发现的分层配置系统。 它非常易于部署,设置和使用,可提供可靠的数据持久性,安全性并具有非常好的文档。

etcd的简单性比Zookeeper更好。 但是,必须先将其与少量第三方工具结合使用,然后才能实现服务发现目标。

服务发现:Zookeeper vs etcd vs Consul

现在我们有了一个存储与我们服务相关的信息的地方,我们需要一个工具来将该信息自动发送到etcd。 毕竟,如果可以自动完成数据,为什么还要手动将数据放入etcd。 即使我们想手动将信息放入etcd,我们通常也不知道该信息是什么。 请记住,服务可能会部署到运行最少容器的服务器上,并且可能会分配一个随机端口。 理想情况下,该工具应在所有节点上监视Docker,并在运行新容器或停止现有容器时更新etcd。 可以帮助我们实现此目标的工具之一是Registrator。

登记员

容器上线或停止时,注册器通过检查容器来自动注册和注销服务。 它目前支持etcdConsulSkyDNS 2

Registratoretcd结合使用是一种强大而简单的结合,使我们可以练习许多高级技术。 每当我们打开一个容器时,所有数据都将存储在etcd中并传播到集群中的所有节点。 我们将如何处理这些信息取决于我们。

服务发现:Zookeeper vs etcd vs Consul

还有另外一个难题。 我们需要一种使用存储在etcd中的数据来创建配置文件以及在创建这些文件时运行一些命令的方法。

confd

confd是轻量级的配置管理工具。 常见用法是使用etcdconsul和其他一些数据注册表中存储的数据来使配置文件保持最新状态。 当配置文件更改时,它也可用于重新加载应用程序。 换句话说,我们可以使用它作为一种使用存储在etcd(或许多其他注册表)中的信息来重新配置所有服务的方法。

服务发现:Zookeeper vs etcd vs Consul

关于etcd,Registrator和confd组合的最终想法

当etcd,Registrator和confd结合使用时,我们将获得一种简单而强大的方法来自动化我们所有的服务发现和配置需求。 这种组合还证明了正确组合“小型”工具的有效性。 这三者正是我们需要他们去做的。 除此之外,我们将无法实现摆在我们面前的目标。 另一方面,如果在设计时考虑到更大的范围,我们将在服务器资源上引入不必要的复杂性和开销。

在做出最终结论之前,让我们看一下具有相似目标的另一种工具组合。 毕竟,在不研究替代方案的情况下,我们永远不应寻求解决方案。

领事

Consul是一个高度一致的数据存储,它使用八卦来形成动态集群。 它具有分层的键/值存储,该键/值存储不仅可以用于存储数据,还可以注册手表,这些手表可以用于各种任务,从发送有关数据更改的通知到根据其输出运行运行状况检查和自定义命令。

与Zookeeper和etcd不同,Consul实现了嵌入式服务发现系统,因此无需构建自己的系统或使用第三方系统。 除其他事项外,该发现还包括对节点和在它们之上运行的服务的运行状况检查。

ZooKeeper和etcd仅提供原始的K / V存储,并要求应用程序开发人员构建自己的系统来提供服务发现。 另一方面,Consul提供了用于服务发现的内置框架。 客户端只需要注册服务并使用DNS或HTTP接口执行发现。 其他两个工具需要手工解决方案或使用第三方工具。

Consul为多个数据中心和八卦系统提供了开箱即用的本机支持,该系统不仅可以在同一集群中的节点之间工作,而且还可以跨数据中心工作。

服务发现:Zookeeper vs etcd vs Consul

领事还有另一个很好的功能,可以与其他人区分开。 它不仅可以用于发现有关已部署服务和它们所驻留的节点的信息,而且还可以通过HTTP请求,TTL(生存时间)和自定义命令轻松扩展健康检查。

登记员

注册器有两个Consul协议。 consulkv协议产生的结果与etcd协议获得的结果相似。

除了通常用etcdconsulkv协议存储的IP和端口之外 ,注册器的consul协议还存储了更多信息。 我们获得有关服务正在运行的节点以及服务ID和名称的信息。 几乎没有其他环境变量,我们还可以标签形式存储其他信息。

服务发现:Zookeeper vs etcd vs Consul

领事模板

confd可以和Consd一起用于Consul。 但是,Consul拥有自己的模板服务,其功能与Consul提供的功能更加一致。

领事模板是使用从领事获得的值创建文件的一种非常方便的方法。 另外,文件更新后,它还可以运行任意命令。 就像confd一样,领事模板也使用Go Template格式。

服务发现:Zookeeper vs etcd vs Consul

领事健康检查,Web UI和数据中心

监视群集节点和服务的运行状况与测试和部署本身一样重要。 尽管我们应该致力于拥有永不失败的稳定环境,但我们也应该承认意外的失败会发生,并准备采取相应的行动。 例如,我们可以监视内存使用情况,如果达到一定的阈值,则将某些服务移至群集中的其他节点。 那将是在“灾难”发生之前采取预防措施的一个例子。 另一方面,并​​非所有可能的故障都能及时发现,以便我们及时采取行动。 单个服务可能会失败。 由于硬件故障,整个节点可能会停止工作。 在这种情况下,我们应该准备尽快采取行动,例如,用一个新节点替换一个节点并移动出现故障的服务。 领事有一种简单,优雅而又强大的方法来执行健康检查,并帮助我们定义达到健康阈值时应执行的操作。

如果您搜索“ etcd ui”或“ etcd仪表盘”,您可能会发现有一些解决方案可用,并且可能会问为什么我们没有提供它们。 原因很简单; etcd是键/值存储,仅此而已。 使用UI来呈现数据并没有多大用处,因为我们可以通过etcdctl轻松获得它。 这并不意味着etcd UI没有用,但是由于范围有限,所以并没有太大的区别。

领事不仅仅是简单的键/值存储。 正如我们已经看到的那样,除了存储简单的键/值对之外,它还具有服务以及属于它的数据的概念。 它还可以执行运行状况检查,因此非常适合用作仪表板,该仪表板可用于查看我们的节点和在它们之上运行的服务的状态。 最后,它理解了多个数据中心的概念。 所有这些功能组合在一起,使我们从不同的角度看待仪表板的需求。

使用Consul Web UI,我们可以查看所有服务和节点,监视运行状况检查及其状态,读取和设置键/值数据以及从一个数据中心切换到另一个数据中心。

服务发现:Zookeeper vs etcd vs Consul

关于领事,注册人,模板,健康检查和Web UI的最终想法

在许多情况下,领事与我们探索的工具一起是比etcd提供的更好的解决方案。 它的设计考虑了服务体系结构和发现。 它简单但功能强大。 它提供了完整的解决方案而又不牺牲简单性,并且在许多情况下,它是满足服务发现和运行状况检查需求的最佳工具。

结论

所有工具都基于相似的原理和体系结构。 它们在节点上运行,需要仲裁才能运行,并且强烈一致。 它们都提供某种形式的键/值存储。

Zookeeper是这三者中最古老的,并且在其复杂性,资源利用和其要实现的目标中显示了年龄。 它的设计年代与我们评估的其他工具不同(即使年代不长)。

Registratorconfd 一起使用的etcd是一个非常简单但功能强大的组合,可以解决大多数(如果不是全部)我们的服务发现需求。 它还展示了当我们结合简单而又非常具体的工具时所能获得的力量。 他们每个人都执行非常具体的任务,通过完善的API进行通信,并且能够相对自主地工作。 它们本身在架构和功能方法上都是微服务

Consul的与众不同之处在于无需使用第三方工具即可支持多个数据中心和运行状况检查。 这并不意味着使用第三方工具是不好的。 实际上,在整个博客中,我们试图通过选择性能优于其他工具而不引入不必要功能开销的工具来组合各种工具。 当我们使用正确的工具完成工作时,可获得最佳结果。 如果该工具无法完成我们所需的工作,则其效率会下降。 另一方面,没有做我们需要做的工具是没有用的。 领事取得平衡。 它做的很少,而且做得很好。

Consul使用八卦传播有关集群的知识的方式使它比etcd更容易建立,尤其是在大数据中心的情况下。 将数据存储为服务的能力使其比etcd中的键/值存储更加完整和有用(即使Consul也具有该选项)。 尽管我们可以通过在etcd中插入多个键来完成相同的操作,但是Consul的服务实现了更为紧凑的结果,通常只需要一个查询即可检索与该服务相关的所有数据。 最重要的是,Registrator对consul协议有很好的实现,这使两者成为了一个很好的组合,尤其是当向该图片添加consul-template时。 领事的Web UI就像蛋糕上的樱桃一样,提供了一种可视化您的服务及其健康状况的好方法。

我不能说领事显然是赢家。 相反,与etcd相比,它有一点优势。 服务发现作为一种概念以及我们可以使用的工具非常新,以至于我们可以期望在该领域中发生许多变化。 保持开放的态度,并尝试从本文中汲取建议。 尝试不同的工具并得出自己的结论。

翻译自: https://www.javacodegeeks.com/2015/09/service-discovery-zookeeper-vs-etcd-vs-consul.html