概述
Consul是一个成熟的服务发现解决方案。其核心是一个基于Raft共识算法具备线性强一致性的Key-Value存储系统作为服务注册中心,并提供代理(Agent)机制一方面用于协调服务注册,一方面提供服务健康检查。代理(Agent)会在每个运行服务的节点上启动,获取节点地址并将该服务实例注册到服务注册中心。架构上Consul包括两类组件:Server、Agent,服务注册信息保存在Server上,通过Raft共识算法保证多个Server间数据线性强一致,保证服务注册中心高可用;将所有Agent作为集群节点,使用Gossip协议进行组关系管理和故障探测,当有Agent加入(启动)或离开(故障)集群时其他Agent会得到通知,实现服务健康检查和监视功能。
Gossip协议常用于集群组关系管理和故障检测,每个节点都通过一个或多个引导节点加入集群,引导节点有集群中所有节点列表,每个节点都从自己所知节点列表中随机选择一组节点周期性地发送多播消息,最终集群中所有节点都能知道其他节点。这个过程看起来很神奇,实际上Gossip协议能在几秒内将消息传遍有上百节点的集群。Akka、Riak、Cassandra都使用Gossip协议维护集群成员列表和故障探测。
服务注册流程

图里的client不是consul里的,是consul使用者。
实现原理
server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是raft。

纵观consul的实现,其核心在于两点:
- 集群内节点间信息的高效同步机制,其保障了拓扑变动以及控制信号的及时传递;gossip
- server集群内日志存储的强一致性。 Raft
它们主要基于以下两个协议来实现:
- 使用gossip协议在集群内传播信息(client和server之间)
- 使用raft协议来保障日志的一致性
首先 Consul 支持多数据中心,
在单个数据中心中,Consul 分为 Client 和 Server 两种节点(所有的节点也被称为 Agent),Server 节点保存数据,Client 负责健康检查及转发数据请求到 Server。
Server 节点有一个 Leader 和多个 Follower,Leader 节点会将数据同步到 Follower,Server 的数量推荐是 3 个或者 5 个,在 Leader 挂掉的时候会启动选举机制产生一个新的 Leader,用的raft保证同步一致性。
集群内的 Consul 节点通过 gossip 协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在还有哪些节点,这些节点是 Client 还是 Server。
Consul Client 可以认为是无状态的,它将注册信息通过 RPC 转发到 Consul Server,服务信息保存在 Server 的各个节点中,并且通过 Raft 实现了强一致性。
每个主机部署 Consul Client, 本机 Client 会将请求转发到 Consul Server。
客户端通常与应用程序一起部署在相同的服务器或容器中。这样docker退出了就会通知consul,然后通知consul server。
监控检查
服务的健康检查由服务注册到的 Agent 来处理。
Consul 的数据同步也是强一致性的,服务的注册信息会在 Server 节点之间同步,相比 ZK、etcd,服务的信息还是持久化保存的,即使服务部署不可用了,仍旧可以查询到这个服务部署。
但是业务服务的可用状态是由注册到的 Agent 来维护的,Agent 如果不能正常工作了,则无法确定服务的真实状态。
对比etcd, zk
| 名称 | 优点 | 缺点 | 接口 | 一致性算法 |
|---|---|---|---|---|
| zookeeper | 1.功能强大,不仅仅只是服务发现 2.提供watcher机制能实时获取服务提供者的状态 3.dubbo等框架支持 | 1.没有健康检查 2.需在服务中集成sdk,复杂度高 3.不支持多数据中心 | sdk | Paxos |
| consul | 1.简单易用,不需要集成sdk 2.自带健康检查 3.支持多数据中心 4.提供web管理界面 | 1.不能实时获取服务信息的变化通知 | http/dns | Raft |
| etcd | 1.简单易用,不需要集成sdk 2.可配置性强 | 1.没有健康检查 2.需配合第三方工具一起完成服务发现 3.不支持多数据中心 | http | Raft |
Key Points
- etcd支持多数据中心
- 有更方便sdk, 命令,有健康检查。 zk和consul可以通过sdk实现健康检查,他们都有ttl内没收到心跳就下线的机制。
- 支持HTTP访问,api丰富。