Consul 基本概念,同类比较和内部原理

Stella981
• 阅读 719

这个文章我们主要来说一下Consul的基本概念,以及其实现的内部原理,和Eureka的比较。

# 1.什么是Consul?
Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面。 这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全服务网格。 Consul需要数据平面并支持代理和本机集成模型。 Consul附带一个简单的内置代理,因此一切都可以开箱即用,但也支持第三方代理集成,如Envoy。
Consul 提供的关键功能:

- 服务发现:Consul的客户端可以注册服务,例如api或mysql,其他客户端可以使用Consul来发现给定服务的提供者。使用DNS或HTTP,应用程序可以轻松找到它们所依赖的服务。
- 运行状况检查:Consul客户端可以提供任意数量的运行状况检查,这些检查与给定服务(“是Web服务器返回200 OK”)或本地节点(“内存利用率低于90%”)相关联。运营人员可以使用此信息来监控群集运行状况,服务发现组件使用此信息将流量路由到远离不健康主机的地方。
- KV 存储:应用程序可以将Consul的层级键/值存储用于任何目的,包括动态配置,功能标记,协调,领导者选举等。简单的HTTP API使其易于使用。
- 安全服务通信:Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。[Intentions](https://www.consul.io/docs/connect/intentions.html)(意图)可用于定义允许哪些服务进行通信。可以使用可以实时更改的意图轻松管理服务分段,而不是使用复杂的网络拓扑和静态防火墙规则。
- 多数据中心:Consul支持多个数据中心。这意味着Consul的用户不必担心构建额外的抽象层以扩展到多个区域。

#2. Consul 的架构
## 2.1 Consul 中的术语
在描述架构之前,我们提供术语表以帮助澄清正在讨论的内容:
- 代理(agent) - 代理是Consul集群的每个成员上长时间运行的守护程序。它是通过运行consul agent 命令来启动的。代理能够以客户端或服务器模式运行。由于所有节点都必须运行代理,因此将节点称为客户端或服务器更简单,但代理还有其他实例。所有代理都可以运行DNS或HTTP接口,并负责运行检查并保持服务同步。

- 客户端模式(client agent) - 客户端是将所有RPC调用转发到服务器的代理。客户端是相对无状态的。客户端执行的唯一后台活动是参与LAN gossip pool(局域网 Gossip池)。这会花费非常非常小的资源并且仅消耗少量的网络带宽。
- 服务器模式(server agent) - 服务器是具有扩展责任的代理,包括参与Raft仲裁,维护群集状态,响应RPC查询,与其他数据中心交换WAN Gossip(广域网Gossip)以及将查询转发给领导者或远程数据中心。

- 数据中心 (datacenter)- 虽然数据中心的定义似乎很明显,但必须考虑细微的细节。例如,在EC2中,多个可用区域是否被视为包含单个数据中心?我们将数据中心定义为专用,低延迟和高带宽的网络环境。这排除了通过公共互联网的通信,但出于我们的目的,单个EC2区域内的多个可用区域将被视为单个数据中心的一部分。

- 共识 (consensus)- 在我们的文档中使用时,我们使用共识来表示对当选领导者的协议以及对交易顺序的协议。由于这些事务应用于[有限状态机](https://en.wikipedia.org/wiki/Finite-state\_machine),因此我们对共识的定义意味着复制状态机的一致性。\[维基百科\](https://en.wikipedia.org/wiki/Consensus\_%28computer\_science%29)上更详细地描述了共识,\[此处\](https://www.consul.io/docs/internals/consensus.html)描述了我们的实现。

- Gossip - Consul建立在[Serf](https://www.serf.io/)之上,它提供了一个完整的\[gossip 协议](https://en.wikipedia.org/wiki/Gossip\_protocol)(八卦协议Gossip协议),用于多种用途。 Serf提供成员维护,故障检测和事件广播。我们对这些的使用在八卦文档中有更多描述。Gossip参与随机的节点到节点的通信,主要是通过UDP。

- LAN Gossip - 指局域网八卦池,其中包含位于同一局域网或数据中心的节点。

- WAN Gossip - 指仅包含服务器(servers)的WAN八卦池。这些服务器主要位于不同的数据中心,通常通过互联网或广域网进行通信。

- RPC - 远程过程调用。这是一种允许客户端发出服务器请求的请求/响应机制。

## 2.2 一万英尺看Consul
![Consul 架构图](https://img-blog.csdnimg.cn/20190607103459828.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1llbGxvd1N0YXI1,size\_16,color\_FFFFFF,t\_70)
让我们分解这个图像并描述每一块。首先,我们可以看到有两个数据中心,标记为“one”和“two”。 Consul为多个数据中心提供一流的支持,并期望这是常见的情况。

在每个数据中心内,我们都有客户端和服务端的混合体。**预计有三到五台服务端。这在失败和性能的可用性之间取得平衡,因为随着更多机器的添加,共识逐渐变慢**。但是,客户端数量没有限制,可以轻松扩展到数千或数万。

**数据中心中的所有节点都参与八卦协议。**这意味着有一个八卦池,其中包含给定数据中心的所有节点。这有几个目的:首先,不需要为客户端配置服务器的地址;发现是自动完成的。其次,检测节点故障的工作不是放在服务器上,而是分布式的。这使得故障检测比天真的心跳方案更具可扩展性。第三,它被用作消息传递层,用于在诸如领导者选举等重要事件发生时进行通知。

每个数据中心中的服务器都是单个Raft对等集的一部分。这意味着他们共同选举一个leader,一个具有额外职责的选定服务器。**领导者负责处理所有查询和交易。作为共识协议的一部分,还必须将事务复制到所有对等体。由于此要求,当非领导者服务器收到RPC请求时,它会将其转发给群集leader。**

**服务器节点作为WAN八卦池的一部分运行**。此池与LAN池不同,因为它针对较高的Internet延迟进行了优化,并且预计仅包含其他Consul服务器节点。此池的目的是允许数据中心以低触摸方式(low-touch manner)发现彼此。在线创建新的数据中心就像加入现有的WAN八卦池一样简单。由于服务器都在此池中运行,因此它还支持跨数据中心请求。**当服务器收到对不同数据中心的请求时,它会将其转发到正确数据中心的随机服务器。然后该服务器可以转发给本地领导者**。

这导致数据中心之间的耦合非常低,但由于故障检测,连接缓存和多路复用,跨数据中心请求相对快速且可靠。

通常,不会在不同的Consul数据中心之间复制数据。当对另一个数据中心中的资源发出请求时,本地Consul服务器会将RPC请求转发给该资源的远程Consul服务器并返回结果。如果远程数据中心不可用,那么这些资源也将不可用,但这不会影响本地数据中心。在某些特殊情况下,可以复制有限的数据子集,例如使用[Consul的内置ACL](https://learn.hashicorp.com/consul/day-2-operations/acl-replication)复制功能,或者像\[consul-replicate\](https://github.com/hashicorp/consul-replicate)这样的外部工具。

在某些地方,客户端代理可以缓存来自服务器的数据,以使其在本地可用,以提高性能和可靠性。示例包括连接证书Connect certificates和意图intentions ,允许客户端代理在没有往返服务器的情况下做出有关入站连接请求的本地决策。某些API端点还支持可选的结果缓存。这有助于提高可靠性,因为本地代理可以继续响应某些查询,例如服务发现或从缓存连接授权,即使与服务器的连接中断或服务器暂时不可用。

# 3. Gossip协议和Raft协议
要想理解Consul的原理,你是绕不过Gossip协议和Raft协议的。

## 3.1 八卦协议Gossip Protocol
### 3.1.1 什么是Gossip 协议
Gossip算法如其名,灵感来自办公室八卦,只要一个人八卦一下,在有限的时间内所有的人都会知道该八卦的信息,这种方式也与病毒传播类似,因此Gossip有众多的别名“闲话算法”、“疫情传播算法”、“病毒感染算法”、“谣言传播算法”。更多,可参见[这篇博文](https://www.cnblogs.com/xingzc/p/6165084.html)
### 3.1.2 Consul中的八卦协议
Consul使用两个不同的八卦池。我们将每个池分别称为LAN或WAN池。

每个数据中心Consul都有一个LAN八卦池,包含数据中心的所有成员,包括客户端和服务器。 LAN池用于一些目的。成员资格信息允许客户端自动发现服务器,减少所需的配置量。分布式故障检测允许整个集群共享故障检测工作,而不是集中在少数服务器上。最后,八卦池允许为领导者选举等事件提供可靠和快速的事件广播。

WAN池是全局唯一的,因为无论数据中心如何,所有服务器都应该参与WAN池。 WAN池提供的成员资格信息允许服务器执行跨数据中心请求。集成故障检测允许Consul优雅地处理丢失连接的整个数据中心,或者只处理远程数据中心中的单个服务器。

所有这些功能都是通过利用[Serf](https://www.serf.io/)提供的。它用作嵌入式库以提供这些功能。从用户的角度来看,这并不重要,因为抽象应该由Consul掩盖。但是,作为开发人员,了解如何利用此库非常有用。

## 3.2 Raft协议
Raft 协议,主要负责leader选举和日志同步。
推荐你看一下[这篇博客](https://www.cnblogs.com/xybaby/p/10124083.html),
你也可以到[这个网站](http://thesecretlivesofdata.com/raft/)通过动画的方式,像玩游戏一样在线体验raft协议的原理。

# 4.和Eureka的比较
Eureka因为是Netflix OSS套件的一部分,2.x停止维护,不过1.x仍然是活跃的。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190607112436458.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1llbGxvd1N0YXI1,size\_16,color\_FFFFFF,t\_70)
这里重点说下consul与Eureka的区别。和其他系统的比较,可[点击此网址自行查看。](https://www.consul.io/intro/vs/index.html)

Eureka是一种服务发现工具。该体系结构主要是客户端/服务器,每个数据中心有一组Eureka服务器,通常每个可用区域一个。通常,Eureka的客户使用嵌入式SDK来注册和发现服务。对于非本地集成的客户端,使用Ribbon等边车通过Eureka透明地发现服务。

**Eureka使用尽力而为的复制提供弱一致的服务视图。当客户端向服务器注册时,该服务器将尝试复制到其他服务器但不提供保证**。服务注册的生存时间(TTL)很短,要求客户端对服务器进行心跳检测。不健康的服务或节点停止心跳后,导致它们超时并从注册表中删除。发现请求可以路由到任何服务,由于尽力复制,这些服务可以提供过时或丢失的数据。这种简化的模型可以实现轻松的集群管理和高可扩展性。

**Consul提供了一系列超级功能,包括更丰富的健康检查,键/值存储和多数据中心感知**。 Consul需要每个数据中心中的一组服务器,以及每个客户端上的代理,类似于使用像Ribbon这样的边车。 Consul代理允许大多数应用程序不知道Consul,通过配置文件执行服务注册以及通过DNS或负载平衡器sidecars进行发现。

**Consul提供强一致性保证,因为服务器使用Raft协议复制状态**。 Consul支持丰富的运行状况检查,包括TCP,HTTP,Nagios / Sensu兼容脚本或基于Ture的Eureka。客户端节点参与基于八卦的健康检查,该检查分发健康检查的工作,而不像集中式心跳,这成为可扩展性挑战。发现请求被路由到当选的领事领导者,这允许他们默认情况下是强烈一致的。允许过时读取的客户端允许任何服务器处理其请求,从而允许像Eureka一样的线性可伸缩性。

**Consul的强一致性意味着它可以用作领导者选举和集群协调的锁服务。 Eureka不提供类似的保证,并且通常需要为需要执行协调或具有更强一致性需求的服务运行ZooKeeper。**

Consul提供了支持面向服务的体系结构所需的功能工具包。这包括服务发现,还包括丰富的运行状况检查,锁定,键/值,多数据中心联合,事件系统和ACL。 Consul和consul-template和envconsul等生态系统工具都试图最大限度地减少集成所需的应用程序更改,以避免需要通过SDK进行本机集成。 Eureka是更大的Netflix OSS套件的一部分,该套件期望应用程序相对同质且紧密集成。因此,Eureka只解决了有限的一部分问题,期望其他工具如ZooKeeper可以同时使用。

总结一下上面的几段话:
- Consul 通过Raft协议提供强一致性,而Eureka提供的弱一致性。
- Consul 通过Gossip协议更好分发健康检查的工作,而不是Eureka集中式心跳(要客户端不停地请求服务端)
- 由于Raft提供的强一致性,Consul可以用来做领导选择,集群协议的锁服务,而Eureka只能借助于Zookeeper。

另外,Spring Cloud官方提供对Consul的支持,网址是https://spring.io/projects/spring-cloud-consul,后面我会写文章具体的使用。

# 5.参考:
https://www.consul.io/intro/index.html
https://www.consul.io/intro/vs/eureka.html
https://www.consul.io/docs/internals/architecture.html
https://www.consul.io/docs/internals/consensus.html
https://www.consul.io/docs/internals/gossip.html
https://www.cnblogs.com/xingzc/p/6165084.html
https://www.cnblogs.com/xybaby/p/10124083.html

文章之后会第一时间发于微信, 欢迎关注我的微信公众号,大家一起交流学习
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190601153218300.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1llbGxvd1N0YXI1,size\_16,color\_FFFFFF,t\_70)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这