1. consul的基本介绍html
在分布式架构中,服务治理是一个重要的问题。在没有服务治理的分布式集群中,各个服务之间经过手工或者配置的方式进行服务关系管理,遇到服务关系变化或者增长服务的时候,人肉配置极其麻烦且容易出错。以前在一个C/C++项目中,采用ZooKeeper进行服务治理,能够很好的维护服务之间的关系,可是使用起来较为麻烦。如今愈来愈多新的项目采用consul进行服务治理,各方面的评价都优于ZooKeeper,通过几天的研究,这里作一个总结。java
开发语言方面,zookeeper采用java开发,安装的时候须要部署java环境;consul采用golang开发,全部依赖都编译到了可执行程序中,即插即用。node
部署方面,zookeeper通常部署奇数个节点方便作简单多数的选举机制。consul部署的时候分server节点和client节点(经过不一样的启动参数区分),server节点作leader选举和数据一致性维护,client节点部署在服务机器上,做为服务程序访问consul的接口。golang
一致性协议方面,zookeeper使用自定义的zab协议,consul的一致性协议采用更流行的Raft。web
zookeeper不支持多数据中心,consul能够跨机房支持多数据中心部署,有效避免了单数据中心故障不能访问的状况。redis
连接方式上,zookeeper client api和服务器保持长链接,须要服务程序自行管理和维护连接有效性,服务程序注册回调函数处理zookeeper事件,并本身维护在zookeeper上创建的目录结构有效性(如临时节点维护);consul 采用DNS或者http获取服务信息,没有主动通知,须要本身轮训获取。算法
工具方面,zookeeper自带一个cli_mt工具,能够经过命令行登陆zookeeper服务器,手动管理目录结构。consul自带一个Web UI管理系统, 能够经过参数启动并在浏览器中直接查看信息。docker
Consul是一个用来实现分布式系统的服务发现与配置的开源工具。他主要由多个组成部分:shell
服务发现:客户端经过Consul提供服务,相似于API,MySQL,或者其余客户端可使用Consul发现服务的提供者。使用相似DNS或者HTTP,应用程序和能够很轻松的发现他们依赖的服务。数据库
检查健康:Consul客户端能够提供与给定服务相关的健康检查(Web服务器返回200 ok)或者本地节点(“内存利用率低于90%”)。这些信息能够监控集群的运行状况,而且使访问远离不健康的主机组件。
键值对存储:应用程序可使用Cousul的层级键值对。
多数据中心:Consul有开箱及用的多数据中心。
client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群.
server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通信, 经过广域网与其余数据中心通信. 每一个数据中心的 server 数量推荐为 3 个或是 5 个.
组成 consul 集群的每一个成员上都要运行一个 agent,能够经过 consul agent
命令来启动。agent 能够运行在 server 状态或者 client 状态。天然的,运行在 server 状态的节点被称为 server 节点;运行在 client 状态的节点被称为 client 节点。
负责转发全部的 RPC 到 server 节点。自己无状态,且轻量级,所以,能够部署大量的 client 节点。
负责组成 cluster 的复杂工做(选举、状态维护、转发请求到 lead),以及 consul 提供的服务(响应 RCP 请求)。考虑到容错和收敛,通常部署 3 ~ 5 个比较合适。
代理(agent):代理是Consul集群上每一个成员的守护进程,它是由consul agent开始运行。代理可以以客户端或服务器模式运行。因为全部节点都必须运行代理,因此将节点引用为客户端或服务器更为简单,但还有其余实例的代理。全部代理能够运行DNS或HTTP接口,并负责运行检查和保持服务同步。
客户端:客户端能够将全部RPC请求转发到服务器的代理。客户端是相对无状态的。客户端执行的惟一后台活动是LANgossip池。它消耗最小的资源开销和少许的网络带宽。
服务器端:服务器端是具备扩展的功能的代理,它主要参与维护集群状态,响应RPC查询,与其余数据中心交换WAN gossip ,以及向上级或远程数据中心转发查询。
数据中心:虽然数据中心的定义彷佛很明显,但仍有一些细微的细节必须考虑。咱们将一个数据中心定义为一个私有、低延迟和高带宽的网络环境。这不包括经过公共互联网的通讯,可是为了咱们的目的,单个EC2区域内的多个可用区域将被视为单个数据中心的一部分
Gossip:consul是创建在serf之上的,它提供了一个完整的gossip协议,用在不少地方。Serf提供了成员,故障检测和事件广播。Gossip的节点到节点之间的通讯使用了UDP协议。
LAN Gossip:指在同一局域网或数据中心的节点上的LAN Gossip池。
WAN Gossip:指包含服务器的WAN Gossip池,这些服务器在不一样的数据中心,经过网络进行通讯。
一致性协议采用 Raft 算法,用来保证服务的高可用.
成员管理和消息广播 采用GOSSIP协议,支持ACL访问控制。
ACL技术在路由器中被普遍采用,它是一种基于包过滤的流控制技术。控制列表经过把源地址、目的地址及端口号做为数据包检查的基本元素,并能够规定符合条件的数据包是否容许经过。
gossip就是p2p协议。他主要要作的事情是,去中心化。
这个协议就是模拟人类中传播谣言的行为而来。首先要传播谣言就要有种子节点。种子节点每秒都会随机向其余节点发送本身所拥有的节点列表,以及须要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。
什么是服务注册?
一个服务将其位置信息在“中心注册节点”注册的过程。该服务通常会将它的主机IP地址以及端口号进行注册,有时也会有服务访问的认证信息,使用协议,版本号,以及关于环境的一些细节信息。
什么是服务发现?
服务发现可让一个应用或者组件发现其运行环境以及其它应用或组件的信息。用户配置一个服务发现工具就能够将实际容器跟运行配置分离开。常见配置信息包括:ip、端口号、名称等。
当一项服务存在于多个主机节点上时,client端如何决策获取相应正确的IP和port。
在传统状况下,当出现服务存在于多个主机节点上时,都会使用静态配置的方法来实现服务信息的注册。
而当在一个复杂的系统里,须要较强的可扩展性时,服务被频繁替换时,为避免服务中断,动态的服务注册和发现就很重要。
图中,客户端的一个接口,须要调用服务A-N。客户端必需要知道全部服务的网络位置的,以往的作法是配置是配置文件中,或者有些配置在数据库中。这里就带出几个问题:
须要配置N个服务的网络位置,加大配置的复杂性
服务的网络位置变化,都须要改变每一个调用者的配置
集群的状况下,难以作负载(反向代理的方式除外)
总结起来一句话:服务多了,配置很麻烦,问题多多
既然有这些问题,那么服务发现就是解决这些问题的。话说,怎么解决呢?咱们再看一张图
与以前一张不一样的是,加了个服务发现模块。图比较简单,这边文字描述下。服务A-N把当前本身的网络位置注册到服务发现模块(这里注册的意思就是告诉),服务发现就以K-V的方式记录下,K通常是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问的了(这就是健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,而后再调用它们的服务。这样的方式是否是就能够解决上面的问题了呢?客户端彻底不须要记录这些服务网络位置,客户端和服务端彻底解耦!
这个过程大致是这样,固然服务发现模块没这么简单。里面包含的东西还不少。这样表述只是方便理解。
图中的服务发现模块基本上就是微服务架构中服务发现的做用了。
consul 简介
作服务发现的框架经常使用的有
zookeeper
eureka
etcd
consul
这里就不比较哪一个好哪一个差了,须要的童鞋本身谷歌百度。
那么consul是啥?consul就是提供服务发现的工具。而后下面是简单的介绍:
consul是分布式的、高可用、横向扩展的。consul提供的一些关键特性:
service discovery:consul经过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也能够同样注册。
health checking:健康检测使consul能够快速的告警在集群中的操做。和服务发现的集成,能够防止服务转发到故障的服务上面。
key/value storage:一个用来存储动态配置的系统。提供简单的HTTP接口,能够在任何地方操做。
multi-datacenter:无需复杂的配置,便可支持任意数量的区域。
咱们这里会介绍服务发现,健康检查,还有一些基本KV存储。多数据中心有机会另外一篇文章再说。
总结:只要知道它是解决我上一部分提出的问题就行,其它的东西慢慢理解
上图是我从consul官方文档抠出来的。
咱们只看数据中心1,能够看出consul的集群是由N个SERVER,加上M个CLIENT组成的。而无论是SERVER仍是CLIENT,都是consul的一个节点,全部的服务均可以注册到这些节点上,正是经过这些节点实现服务注册信息的共享。除了这两个,还有一些小细节,一一简单介绍。
CLIENT
CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,全部注册到当前节点的服务会被转发到SERVER,自己是不持久化这些信息。
SERVER
SERVER表示consul的server模式,代表这个consul是个server,这种模式下,功能和CLIENT都同样,惟一不一样的是,它会把全部的信息持久化的本地,这样遇到故障,信息是能够被保留的。
SERVER-LEADER
中间那个SERVER下面有LEADER的字眼,代表这个SERVER是它们的老大,它和其它SERVER不同的一点是,它须要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。
其它信息
其它信息包括它们之间的通讯方式,还有一些协议信息,算法。它们是用于保证节点之间的数据同步,实时性要求等等一系列集群问题的解决。这些有兴趣的本身看看官方文档。
相关开源项目:Zookeeper,Doozer,Etcd,强一致性的项目,这些项目主要用于服务间的协调,同时又可用于服务的注册。
什么是强一致性协议?
按照某一顺序串行执行存储对象读写操做, 更新存储对象以后, 后续访问老是读到最新值。 假如进程A先更新了存储对象,存储系统保证后续A,B,C进程的读取操做都将返回最新值。强一致性模型有几种常见实现方法, 主从同步复制, 以及quorum复制等。
http://blog.csdn.net/shlazww/article/details/38736511
1. docker、coreos 实例的注册与配置共享
2. vitess集群
3. SaaS应用的配置共享
4.与confd服务集成,动态生成nignx与haproxy配置文件
1. 使用 Raft 算法来保证一致性,比poxes算法更直接。zookeeper采用的时poxes算法。
Raft大概将整个过程分为三个阶段,leader election,log replication和commit(safety)。
每一个server处于三个状态:leader,follower,candidate。正常状况下,全部server中只有一个是leader,其它的都是follower。server之间经过RPC消息通讯。follower不会主动发起RPC消息。leader和candidate(选主的时候)会主动发起RPC消息。
首先选择一个leader全权负责管理日志复制,leader从客户端接收log entries,将它们复制给集群中的其它机器,而后负责告诉其它机器何时将日志应用于它们的状态机。举个例子,leader能够在无需询问其它server的状况下决定把新entries放在哪一个位置,数据永远是从leader流向其它机器。一个leader能够fail或者与其余机器失去链接,这种情形下会有新的leader被选举出来。
http://www.jdon.com/artichect/raft.html
http://blog.csdn.net/cszhouwei/article/details/38374603
2. 支持多数据中心,内外网的服务采用不一样的端口进行监听。这样能够避免单点故障。
zookeeper等不支持多数据中心功能的支持
3. 支持健康检查
4. 提供web界面
5. 支持http协议与dns协议接口
使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
支持多数据中心,内外网的服务采用不一样的端口进行监听。 多数据中心集群能够避免单数据中心的单点故障,而其部署则须要考虑网络延迟, 分片等状况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
支持健康检查. etcd 不提供此功能.
支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议.
官方提供web管理界面, etcd 无此功能.
综合比较, Consul 做为服务注册和配置管理的新星, 比较值得关注和研究.
图中有两个数据中心,分别为Datacenter1和Datacenter2。Consul一层支持多个数据中心,每一个数据中心内,有客户端和服务器端,服务区端通常为3~5个,这样能够在稳定和性能上达到平衡,由于更多的机器会使数据同步很慢。不过客户端是没有限制的,能够有成千上万个。
数据中心到全部节点都使用的时候Gossip协议。这就意味着有一个Gossip池,其中包含给定数据中心全部的节点。客户端不须要去配置服务器地址信息,发现服务会自动完成;检测故障节点的工做不是放在服务器端,而是分布式的;数据中心被用做消息层,以便在选择leader这种重要的事情发生的时候作通知。
每一个数据中心都是都是单个Raft对等设备的一部分。这意味着他们一块儿工做,选择一个单一的领导者——一个具备额外职责的选定的服务器。leader负责处理全部查询和事物。事物也必须做为同步协议的一部分复制到全部对等体。因为这个要求,当非领导服务器端接收到RPC请求时,就会将请求其转发给集群leader。
服务器端节点做为WANGossip池的一部分运行,WAN池和LAN池不一样的是,针对网络高延迟作了优化,并且只包含其余Consul服务器的节点。这个池的目的是容许数据中心以最少的消耗方式发现对方。在线启动新的数据中心与加入现有的WAN Gossip同样简单。由于这些服务器都在这个池中运行,它还支持跨数据中心请求。当服务器收到对不一样数据中心的请求时,它会将其转发到正确数据中心中的随机服务器。那个服务器可能会转发给本地的leader。
这样会使数据中心的耦合很是低,因为故障检测,链接缓存和复用,跨数据中心请求相对快速可靠。
Consul使用Gossip协议来管理成员和集群广播消息,这些都是经过使用Serf库的。Serf所使用的Gossip协议基于SWIM:可伸缩的弱一致的感染模式的过程组成员协议”,并作了一些细微的修改。
Consul使用了两个不一样的Gossip池,称为LAN池和WAN池。每一个数据中心都有一个LAN池,其中包含数据中心的全部成员,包括服务器端和客户端。LAN的成员客户端能够自动发现服务器,减小所需配置的数量。分布式故障检测可让故障检测的工具被整个集群共享,Gossip池能够快速可靠的将事件广播,好比选择leader。
WAN池是全局惟一的,全部的服务器都应该在WAN池中,而不关系数据中心在哪里。WAN池提供的成员信息容许服务器执行跨数据中心请求。集成的故障检测功能使Consul可以优雅地处理整个数据中心或者远程数据中心的一个服务器失连。
在分组软实时处理可能的状况下,SWIN假设本地节点是健康的。但在本地节点遇到CPU或者网络节点资源匮乏的时候,可能不会认为节点不健康。结果是安全检测状态可能会偶尔瘫痪,致使虚假报警。Lifeguard解决了这个问题。
Consul经过Consensus协议来提供一致性(由CAP定义)。Consensus协议是基于Raft——查找可理解的一致性算法。
Raft是一种基于Paxos的一致性算法。与Paxos相比,Raft被设计成更少的状态和更简单、更易于理解的算法。
Raft节点有三种状态:follower,candidate,leader.全部的节点初始被置于follower,在这个状态下的节点均可以收到来自leader的Log并反馈。若是在一段时间没有收到任何信息,那么他就会变成candidate状态。在candidate状态下,一个节点向其余节点发送请求,这个节点就成为了leader。Leader必须接收新Log并复制其到其余follower那里。PS:只有leader才能进行读取Log。
一旦一个集群有一个leader,他就能够接受新的Log条目。一个客户端能够请求leader附加新的Log条目。这个leader随后将Log条目写入持久存储,并复制到follower。一旦Log条目被认为已经提交,它就会被用于有限状态机。有限状态机是相对于特定应用的,对于Consul而言,咱们使用MenDB来维护集群状态。
显然,咱们不须要无限制的复制日志。Raft提供了一种机制,经过这种机制,让状态被记录时这个Log就会被压缩。
Consul使用网络断层成像系统计算集群中的节点的网络坐标。这些坐标能够计算在任何两个节点之间估计网络往返时间。这有不少有用的应用,例如找到最靠近请求节点的服务节点,或者找到在下一个失效的最接近的数据中心中的服务器。
在Consul里,网络坐标有几种形式:
consul rtt命令能够查询任意两个节点的网络往返之间。
显示端点和端点运行情况端点可使用“?near =”参数根据给定节点的网络往返时间对查询的结果进行排序。
查询能够根据网络往返时间将请求从故障的数据中心服务器中转移。
坐标终点显示用于其余应用程序的原始网络坐标。
Consul提供了Session机制用于构建分布式锁,Session做为节点之间的绑定,运行情况检查和键值对数据。
Consul的session表明了具体语义一个Session中包含了节点名称,列表的健康性,行为,TTL和lock-delay。新建的Session中提供了一个能够用来识别它的ID。这个ID可与存储的键值对一块儿使用以获取锁定:相互排斥的咨询机制。
下图是组件之间的关系图:
Consul定制的标准在下列状况下,被定义为无效:
节点被注销
全部的健康检查都被注销
全部健康检查都在危险状态
Session被明确销毁了
TTL过时
Session无效的时候,将会被销毁,关联锁是建立的指定行为,Consul支持发布和删除。Consul支持释放和删除行为,若是没有特别指定,默认的行为为释放。
若是正在执行释放操做,与Session相关的全部的锁都会被释放掉,而且键的索引没法递增。在删除行为执行的时候,则锁和键都会被删除。这能够用于Consul自动删除条目。
这种设计经常使用于流言传播的故障检测器的健康监测。在默认状况下,使用基于留言传播的故障检测器做为故障检测器用来进行相关的健康检查。该故障检测器容许Consul检测持有锁的节点在发生故障时自动释放锁。这种机制让consul发生故障或者其余失败的状况下,能够继续运行下去。可是,因为,没有完美的故障检测器,有的时候,检测到的故障并不存在,也会致使锁的释放。这就意味着他并非绝对安全的。
相反的,能够建立一个无关联的健康检测的session。这就提供了对安全性要求的虚假的不健康检测的消除提供了可能。即便现有的锁的持有者执行出现故障,你也能够本身肯定是否释放Consul的锁。因为Consul的API能够强制销毁session,因此咱们能够在发生故障的时候进行人为干预,防止split-brain。
第三个健康检测机制是session的TTL。当建立一个session的时候,一个TTL也被指定。若是这个TTL的间隔时间到而没有更新,则session过时,而且没法早触发。这种类型的故障检测器叫作心跳检测器。他想必基于流言传播的故障检测器的可扩展性低,由于他会对服务器形成更大的负担,可是在一些状况下颇有用。TTL是session过时的时间,在到达TTL以前,consul不会让session过去,可是consul容许延迟过时。在session建立初期,session更新和leader故障转移的时候,TTL会更新。当一个TTL被使用的时候,客户端应当注意时间的误差——时间不可能会像consul Server上那样在客户端上以相同的速率进展。咱们最好设置保守的TTL值,TTL更新以前考虑时间的误差。
最后的细微差异为session会提供锁定延迟。这个延迟会持续0-60秒。当有无效的session时,consul会防止ssession在锁定延时的时间内从新获取以前的保存的全部锁。这种延迟的目录是容许潜在的leader检测到无效后,中止并致使状态不一致的请求。虽然不是一个完全的方式,可是能够减小不少问题。延迟默认为15秒,客户端能够将延迟设置为0来取消这个机制。
Consul使用了流言传播协议和RPC来提供各类功能。这两个系统在设计上采用了不一样的安全机制,可是,Consul的安全机制完成的共同目标为:提供机密性,完整性和认证。流言传播协议由serf提供支持,serf使用对称秘钥或者共享密码系统。RPC支持使用可选客户端认证的端到端的TLS。
这就意味着Consul有完善的安全机制可使其在不可信的网络上运行。
如下是威胁模型:
非成员能够访问数据
因为恶意邮件致使集群被操控
恶意邮件形成的虚假数据
对接点拒接服务
Consul使用命令行很是容易操做,咱们能够经过命令consul进行命令行申请。而后接着使用agent或者member之类的子命令。只要运行不带参数的consul命令就能够查看命令列表。
想要得到的顶的命令的帮助,可使用-h获取帮助,以下:
Agent是Consul的核心,用来运行代理者,维护成员的信息,运行检测,处理查询信息等。
该命令用来接Consul目录进行交互。
event提供了一种将自定义用户事件触发到整个数据中心的机制,这些事件对Consul是不透明的,但它们可用于构建脚本基础架构,以进行自动部署,从新启动服务或执行任何其余编排操做。Event能够经过使用watch来处理。event的传播是经过流言传播协议的。
exec命令提供了远程执行的机制。下表显示了执行此命令索要的ACL。
ACL Required | 范围 |
---|---|
agent:read | 本地agent |
session:write | 本地agent |
key:write | "_rexec"字首 |
event:write | "_rexec"字首 |
info命令提供了对运算符有用的各类调试信息。根据代理是客户端仍是服务器,将返回不一样的子系统信息。目前有几个顶级的键:
agent:提供有关agent的信息
consul:有关consul的信息——客户端或者服务器端
raft:提供有关Raft公共信息
serf_lan:提供有关LAN流言池的信息
serf_wandf:提供有关WAN流言池的信息
join命令让Consul代理加入一个现有集群,新的Consul代理必须与集群的至少一个现有成员共同参与现有的集群。加入该成员后,流言层接管,跨集群传播更新成员的资格状态。若是没有加入现有的集群,则代理是本身的孤立集群的一部分,其余节点能够加入。
代理能够加入其它的代理。若是已是集群的一部分的节点加入了另外一个节点,则两个节点的集群将加入成为一个集群。
keygen命令生成可用于Consul代理流量加密的加密秘钥。
keyring命令用于检查和修改Consul的流言池中使用的加密密钥。
lock命令提供了简单分布式锁定的机制。在KV存储中的给定前缀建立锁(或信号量),只有当被保持时,才会调用子进程。若是锁丢失或通讯中断,则子进程终止。锁定器的数量可使用-n标志进行配置。默认状况下,容许单个持有人,而且使用锁来进行互斥。这使用leader选举算法。
menber命令输出Consul代理人知道的当前成员名单及其状态。节点的状态只能是“alive”,“left”或“failed”。
monitor命令用于链接和跟踪正在运行的Consul代理的日志。Monitor将显示最近的日志,而后继续遵循日志,不会退出直到中断或直到远程代理退出。
reload命令触发代理程序从新加载配置文件。
snapshot命令具备用于保存,恢复和检查Consul服务器的状态用于容灾恢复的子命令。这些是原子的时间点快照,其中包括键值条目,服务目录,准备好的查询,会话和ACL。 Consul 0.7.1及更高版本中提供此命令。
Consul的Agent是Consul的核心。Agent维护成员的信息,注册服务,运行检测,响应查询。Agent必须做为Consul集群的一部分的每一个节点上运行。任何代理能够以两种模式之一运行:客户端或者服务器。服务器节点承担了协商一致性的功能。这些节点参与了Raft,并在故障下提供了强大的一致性和可用性。服务器节点负担愈来愈大意味着须要在专用的实例上运行——他们比客户端节点更为资源密集。客户端节点构成了大多数的集群,而且它们很轻量,由于它们大多数操做的是服务器节点接口,维护本身状态的时间不多。