抄自这里

************************************************************************************************

网上找来找去都是zk和etcd的比较,和consul的比较很少,这个感觉还算靠谱,也在别的地方看到过对consul的吐槽,记录下

************************************************************************************************

导语

在分布式微服务架构中,一个应用可能由一组职责单一化的服务组成。这时候就需要一个注册服务的机制,注册某个服务或者某个节点是可用的,还需要一个发现服务的机制来找到哪些服务或者哪些节点还在提供服务。

在实际应用中,通常还都需要一个配置文件告诉我们一些配置信息,比如数据连接的地址,redis 的地址等等。但很多时候,我们想要动态地在不修改代码的情况下得到这些信息,并且能很好地管理它们。

有了这些需求,于是发展出了一系列的开源框架,比如 ZooKeeper, Etcd, Consul 等等。

这些框架一般会提供这样的服务:

服务注册
主机名,端口号,版本号,或者一些环境信息。

服务发现
可以让客户端拿到服务端地址。

一个分布式的通用 k/v 存储系统
基于 Paxos 算法或者 Raft 算法

领导者选举 (Leader Election)

其它一些例子:
分布式锁 (Distributed locking)
原子广播 (Atomic broadcast)
序列号 (Sequence numbers)

我们都知道 CAP 是 Eric Brewer 提出的分布式系统三要素:
强一致性 (Consistency)
可用性 (Availability)
分区容忍性 (Partition Tolerance)

几乎所有的服务发现和注册方案都是 CP 系统,也就是说满足了在同一个数据有多个副本的情况下,对于数据的更新操作达到最终的效果和操作一份数据是一样的,但是在出现网络分区(分区间的节点无法进行网络通信)这样的故障的时候,在节点之间恢复通信并且同步数据之前,一些节点将会无法提供服务(一些系统在节点丢失的情况下支持 stale reads )。

ZooKeeper 作为这类框架中历史最悠久的之一,是由 Java 编写。Java 在许多方面非常伟大,然而对于这种类型的工作还是显得有些沉重,也正因为其复杂性和对新鲜事物的向往,我们第一时间就放弃了选择它。

本文将从协议和应用层来比较 Etcd 和 Consul,并最终给出了笔者的偏好。

Etcd

Etcd 是一个使用 go 语言写的分布式 k/v 存储系统。考虑到它是 coreos 公司的项目,以及在 GitHub 上的 star 数量 (9000+),Google 著名的容器管理工具 Kuberbetes 就是基于 Etcd 的。我们最先考虑的就是它。

在介绍 Etcd 之前,我们需要了解一些基本的概念。我们知道在单台服务器单个进程中维护一个状态是很容易的,读写的时候不会产生冲突。即便在多进程或者多线程环境中,使用锁机制或者协程(coroutine)也可以让读写有序地进行。但是在分布式系统中,情况就会复杂很多,服务器可能崩溃,节点间的机器可能网络不通等等。所以一致性协议就是用来在一个集群里的多台机器中维护一个一致的状态。

很多的分布式系统都会采用 Paxos 协议,但是 Paxos 协议难以理解,并且在实际实现中差别比较大。所以 Etcd 选择了 Raft 作为它的一致性协议。Raft 是 Diego Ongaro 和 John Ousterhout 在 ‘In Search of an Understandable Consensus Algorithm’ 中提出的。它在牺牲很少可用性,达到相似功能的情况下,对 Paxos 做了很大的优化,并且比 Paxos 简单易懂很多。

它主要集中在解决两个问题:

领导者选举(Leader Election)
Raft 先通过领导选举选出一个 Leader,后续的一致性维护都由 Leader 来完成,这就简化了一致性的问题。Raft 会保证一个时间下只会有一个 Leader,并且在超过一半节点投票的情况下才会被选为 Leader。当 Leader 挂掉的时候,新的 Leader 将会被选出来。

日志复制 (Log Replication)
为了维护状态,系统会记录下来所有的操作命令日志。Leader 在收到客户端操作命令后,会追加到日志的尾部。然后 Leader 会向集群里所有其它节点发送 AppendEntries RPC 请求,每个节点都通过两阶段提交来复制命令,这保证了大部分的节点都能完成。

在实际的应用中,一般 Etcd 集群以 5 个或者 7 个为宜,可以忍受 2 个或者 3 个节点挂掉,为什么不是越多越好呢?是出于性能的考虑,因为节点多了以后,日志的复制会导致 CPU 和网络都出现瓶颈。

Etcd 的 API 比较简单,可以对一个目录或者一个 key 进行 GET,PUT,DELETE 操作,是基于 HTTP 的。Etcd 提供 watch 某个目录或者某个 key 的功能,客户端和 Etcd 集群之间保持着长连接 (long polling)。基于这个长连接,一旦数据发生改变,客户端马上就会收到通知,并且返回的结果是改变后的值和改变前的值,这一点在实际应用中会很有用(这也是后面的 Consul 的槽点之一)。

Etcd 的 watch 和在一般情况下不会漏掉任何的变更。因为 Etcd 不仅存储了当前的键值对,还存储了最近的变更记录,所以如果一个落后于当前状态的 watch 还是可以通过遍历历史变更记录来获取到所有的更新。Etcd 还支持 CompareAndSwap 这个原子操作,首先对一个 key 进行值比较,只有结果一致才会进行下一步的赋值操作。利用这个特性就像利用 x86 的 CAS 实现锁一样可以实现分布式锁。

在 Etcd 中有个 proxy 的概念,它其实是个转发服务器,启动的时候需要指定集群的地址,然后就可以转发客户端的请求到集群,它本身不存储数据。一般来说,在每个服务节点都会启动一个 proxy,所以这个 proxy 也是一个本地 proxy,这样服务节点就不需要知道 Etcd 集群的具体地址,只需要请求本地 proxy。之前提到过一个 k/v 系统还应该支持 leader election,Etcd 可以通过 TTL (time to live) key 来实现。

Consul

Consul 和 Etcd 一样也有两种节点,一种叫 client (和 Etcd 的 proxy 一样) 只负责转发请求,另一种是 server,是真正存储和处理事务的节点。

Consul 使用基于 Serf 实现的 gossip 协议来管理从属关系,失败检测,事件广播等等。gossip 协议是一个神奇的一致性协议,之所以取名叫 gossip 是因为这个协议是模拟人类中传播谣言的行为而来。要传播谣言就要有种子节点,种子节点每秒都会随机向其它节点发送自己所拥有的节点列表,以及需要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。这个协议的神奇就在于它从设计开始就没想要信息一定要传递给所有的节点,但是随着时间的增长,在最终的某一时刻,全网会得到相同的信息。当然这个时刻可能仅仅存在于理论,永远不可达。

Consul 使用了两个不同的 gossip pool,分别叫做 LAN 和 WAN,这是因为 Consul 原生支持多数据中心。在一个数据中心内部,LAN gossip pool 包含了这个数据中心所有的节点,包括 proxy 和 servers。WAN pool 是全局唯一的,所有数据中心的 servers 都在这个 pool 中。这两个 pool 的区别就是 LAN 处理的是数据中心内部的失败检测,事件广播等等,而 WAN 关心的是跨数据中心的。除了 gossip 协议之外,Consul 还使用了 Raft 协议来进行 leader election,选出 leader 之后复制日志的过程和 Etcd 基本一致。

回到应用层面上来说,Consul 更像是一个 full stack 的解决方案,它不仅提供了一致性 k/v 存储,还封装了服务发现,健康检查,内置了 DNS server 等等。这看上去非常美好,简直可以开箱即用。于是,我们初步选定了 Consul 作为我们的服务发现和动态配置的框架。但现实往往是冰冷的,在深入研究它的 API 之后发现了比较多的坑,可能设计者有他自己的考虑。

在使用获取所有 services 的 API 的时候返回的只是所有服务的名字和 tag,如果想要每个服务的具体信息,你还需要挨个去请求。这在客户端就会十分不方便,因为在笔者看来,获取所有服务的列表以及具体信息应该是一个很常见的需求,并且请求的次数越少越好。

如果 watch 服务是否有变化,当值发生改变的时候,返回的结果居然是相当于重新读取所有 services,没有能够体现出服务信息的变化,这会导致客户端很难进行更新操作。

健康检查是 Consul 的内置功能,在注册一个服务的时候可以加上自定义的健康检查,这听上去很不错。但是如果你忘记给你某个服务加上健康检查,那它在各种 API 的返回结果中变得难以预料。

结语

在折腾了数天之后,最终我们决定回归 Etcd,事实证明这个决定是正确的。我们基于 Etcd 实现了稳定的服务发现和动态配置功能,当然还有一些比较细节的问题没有在文中阐述,欢迎一起探讨。

服务发现之 Etcd VS Consul的更多相关文章

  1. 服务发现系统etcd之安装和使用

    一.概述 etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致 ...

  2. 服务发现框架选型,Consul还是Zookeeper还是etcd

    背景 本文并不介绍服务发现的基本原理.除了一致性算法之外,其他并没有太多高深的算法,网上的资料很容易让大家明白上面是服务发现. 想直接查看结论的同学,请直接跳到文末. 目前,市面上有非常多的服务发现工 ...

  3. 我是服务的执政官-服务发现和注册工具consul简介

    服务发现和注册 我们有了两个服务.服务A的IP地址是192.168.0.1,端口9001,服务B的IP地址192.168.0.2,端口9002.我们的客户端需要调用服务A和服务B,我们只需要在配置文件 ...

  4. 基于 Consul 的 Docker Swarm 服务发现

    Docker 是一种新型的虚拟化技术,它的目标在于实现轻量级操作系统的虚拟化.相比传统的虚拟化方案,Docker 虚拟化技术有一些很明显的优势:启动容器的速度明显快于传统虚拟化技术,同时创建一台虚拟机 ...

  5. 服务发现之consul理论整理_结合Docker+nginx+Tomcat简单部署案例

    目录 一.理论概述 服务发现的概念简述 consul简述 二.部署docker+consul+Nginx案例 环境 部署 三.测试 四.总结 一.理论概述 服务发现的概念简述 在以前使用的是,N台机器 ...

  6. 来,Consul 服务发现入个门(一看就会的那种)

    前言 在微服务架构中,对于一个系统,会划分出多个微服务,而且都是独立开发.独立部署,最后聚合在一起形成一个系统提供服务.当服务数量增多时,这些小服务怎么管理?调用方又怎么能确定服务的IP和端口?服务挂 ...

  7. etcd:用于服务发现的键值存储系统

    etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理 ...

  8. Redola.Rpc 集成 Consul 服务发现

    Redola.Rpc 解决了什么问题? Redola.Rpc 是一个使用 C# 开发的 RPC 框架,代码开源在 GitHub 上.目前版本仅支持 .NET Framework 4.6 以上版本,未来 ...

  9. Prometheus Consul实现自动服务发现

    Prometheus Consul实现自动服务发现   1.概述 Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件. Consul 由 HashiCorp公司用Go语言开发 ...

随机推荐

  1. Django URL传递参数的方法总结(转)

    1 无参数情况 配置URL及其视图如下: 1 2 3 4 (r'^hello/$', hello)   def hello(request): return HttpResponse("He ...

  2. MVP -----个人理解与示例(android例子 实现)

    MVP 也就是Model View Presenter模式,是建立一个工程的一种模式. ======================================================== ...

  3. python编程技巧2

    模块化 ---- 这是我们程序员梦寐以求的,通过模块化可以避免重复的制造轮子. 同时 模块让你能够有逻辑地组织你的Python代码段. 把相关的代码分配到一个 模块里能让你的代码更好用,更易懂. 模块 ...

  4. OllyDBG 1.10

    OllyDBG 1.10 OllyDBG.exeOllyDBG SoftICE文件->打开 (快捷键是 F3)F2 断点 F9F8 步过 F10F7 步入 F8F4 运行到位置 F7F9 运行 ...

  5. 关于在biweb 中安装完成后 首页上方报错问题的解决

    在利用biweb进行网站开发的时候 首先得安装biweb    安装就是下一步,,,下一步....下一步   最后就成功了 .但是有种情况我总是竟让遇到,而已有的人安装会遇到 有的人安装就不会遇到,后 ...

  6. 联想 thinkpad fn键关闭,优化使用

    工作给配的电脑是,联想 thinkpad E431,fn键真的是很不合理的设计. 首先,从位置上来讲,这个fn键应该是ctrl才符合通常键盘的操作习惯. 其次,从功能上来讲,当我调是程序的时候,按F6 ...

  7. iOS开发拓展篇—应用之间的跳转和数据传递

    iOS开发拓展篇—应用之间的跳转和数据传 说明:本文介绍app如何打开另一个app,并且传递数据. 一.简单说明 新建两个应用,分别为应用A和应用B. 实现要求:在appA的页面中点击对应的按钮,能够 ...

  8. 解决cocopods不提示第三方库名字的方法

    在使用第三方类库时,使用cocoaPods是非常方便的,具体使用方法可以参考:CocoaPods安装和使用教程 的安装使用方法.今天讨论的问题是,我在使用的时候遇到了一些问题:用cocoaPod si ...

  9. Jmeter教程索引

    一.基础部分: 使用Jmeter进行http接口测试 Jmeter之Http Cookie Manager Jmeter之HTTP Request Defaults Jmeter之逻辑控制器(Logi ...

  10. CSU 1325 莫比乌斯反演

    题目大意: 一.有多少个有序数对(x,y)满足1<=x<=A,1<=y<=B,并且gcd(x,y)为p的一个约数: 二.有多少个有序数对(x,y)满足1<=x<=A ...