Consul作为注册中心,提供服务发现、配置、健康检查、安全服务通信以及多数据中心等功能, 这些功能可以根据需要单独使用,也可以一起使用来构建完整的微服务系统。
Consul agent是Consul的核心进程。它是运行在Consul节点上,这些节点共同组成Consul集群。agent
进程用于维护成员信息、注册服务、成员健康检查等功能,agent
有如下两种模式运行:
agent
不可达,则节点可能出现故障。Client节点缓存server节点的数据,用以提高性能和可用性。从官网下载Consul压缩包。
解压启动。如下:
[root@unite-test consul]# consul agent -data-dir=/tmp/consul -node=server184.43 -datacenter=unite-dc -server=true
==> Starting Consul agent...Version: 'v1.7.2'Node ID: '74124b5b-aedc-59c3-5e6c-436443f2c025'Node name: 'server184.43'Datacenter: 'unite-dc' (Segment: '
==> Consul agent running!
....
通过consul agent
命令启动成功后,通过日志输出有如下关键信息。如下:
-node
配置自定义设置节点名字-datacenter
配置数据中心名字-server
配置。该节点状态处于正常状态。 当agent节点首次启动时,通过如下配置自动完成加入集群中。一旦节点加入集群后,该节点的信息会传递给整个集群,集群中所有的节点成员都会知道彼此的存在。如果该节点是Server模式运行的,其它Server节点会进行日志复制。
retry_join = ["172.26.4.38","172.26.4.125"]
当出现网路故障或者agent
进程关闭时,这些节点可能无法被其它节点访问,把这些节点标记为失败(failed)状态。 此时对failed状态的节点,Consul Server(领导者)节点会尝试重新连接该节点。可以看到leader节点日志输出如下:
# client29.118 has failed, no acks received
2021-11-24T16:10:06.279+0800 [INFO] agent.server.memberlist.lan: memberlist: Suspect client29.118 has failed, no acks received
2021-11-24T16:10:10.268+0800 [INFO] agent.server.serf.lan: serf: EventMemberFailed: client29.118 172.24.29.118
2021-11-24T16:10:10.269+0800 [INFO] agent.server: member failed, marking health critical: member=client29.118
2021-11-24T16:10:36.310+0800 [INFO] agent.server.serf.lan: serf: attempting reconnect to client29.118 172.24.29.118:8301
2021-11-24T16:12:06.314+0800 [INFO] agent.server.serf.lan: serf: attempting reconnect to client29.118 172.24.29.118:8301
从日志输出看出,当节点标记为故障状态,leader节点会默认每隔30s尝试重新进行连接。此时通过Consul命令查看节点状态,client29.118节点状态是failed状态。如下:
[root@unite-test consul]# consul members
Node Address Status Type Build Protocol DC Segment
server29.6 172.24.29.6:8301 alive server 1.7.2 2 test-leave-dc <all>
server29.9 172.24.29.9:8301 alive server 1.7.2 2 test-leave-dc <all>
service29.186 172.24.29.186:8301 alive server 1.7.2 2 test-leave-dc <all>
client29.118 172.24.29.118:8301 failed client 1.7.2 2 test-leave-dc <default>
注意
:当网络恢复或者agent被重新启动&#xff0c;节点状态更新为正常&#xff08;alive&#xff09;状态。
对于failed状态的节点&#xff0c;默认72小时&#xff0c;Consul会完全的把它从集群中移除掉&#xff0c;此时的节点标记为离开&#xff08;left&#xff09;状态&#xff0c;和失败状态&#xff08;failed&#xff09;不同。left状态节点上注册所有服务会被删除&#xff0c;如果节点是server模式启动&#xff0c;停止对它的日志复制。该值由如下参数设置。
reconnect_timeout &#61; "1h" //可以用“s”、“m”、“h”表示秒、分钟或小时。该值必须为大于8小时。
注意
建议将其值设置为节点或者网路分区的最大预期恢复中断的两倍。时间设置过低可能会导致节点故障或者网络分区期间&#xff0c;从Consul集群中删除节点&#xff0c;导致集群恢复复杂。对于failed状态的节点&#xff0c;可以在其它节点发送HTTP请求&#xff0c;强制把它从failed状态变成left状态&#xff0c;对left状态的节点&#xff0c;leader节点不会尝试重新连接。
curl http://172.24.29.186:8500/v1/agent/force-leave/client29.118
leader节点日志变化如下:
2021-11-24T16:27:13.767&#43;0800 [INFO] agent.server.serf.lan: serf: EventMemberLeave (forced): client29.118 172.24.29.118
2021-11-24T16:27:13.767&#43;0800 [INFO] agent.server: deregistering member: member&#61;client29.118 reason&#61;left
对于left状态节点&#xff0c;serf
组件内有tombstone_timeout
参数控制left状态的节点被收割需要时间。收割理解为节点是left状态&#xff0c;从成员中移除掉。默认24小时后&#xff0c;left状态的节点从成员中移除掉。
注意
agent进程优雅的关闭&#xff0c;节点会从alive状态变为left状态。
下图表示是系统中多数据中心组成Consul集群架构图。每个数据中心都是局域网内Consul集群。如下图所示&#xff0c;有两个数据中心&#xff0c;分别是DATACENTER1
和DATACENTER2
。不同的数据中心之间不会进行数据同步&#xff0c;但是可以通过RPC请求其它数据中心数据。 在DATACENTER1
的数据中心&#xff0c;存在两种启动模式agent节点&#xff0c;分别是Server和Client。
从上图看出Consul需要多个不同的端口才能正常工作&#xff0c;其中一些端口使用TCP、UDP或者两种协议。主要端口详情如下&#xff1a;
所有Consul Server节点参与Raft协议&#xff0c;共同组成Peer Set
。Peer set
理解为参与日志复制所有成员的集合。所有Consul Client节点把请求转发给Consul Server节点。这种设计主要原因是&#xff0c;随着更多Consul节点成员的加入到Peer Set
中。 quorum
的大小也会增加。quorum
理解为多数派。对于N个Consul Server节点成员&#xff0c;quorum
要求至少有(N/2)&#43;1成员。例如&#xff0c;peer set有5个Server节点&#xff0c;就须要至少3个节点才能造成quorum。
注意
: Raft协议理解共识&#xff08;Consensus&#xff09;协议。
当Consul通过Server模式启动agent进程时&#xff0c;这种模式允许它们选举出领导者。通过查看Consul启动日志看出选举过程&#xff0c;如下通过三个Server节点组成Peer set
参与选举。
引导模式启动&#xff0c;通过配置bootstrap_expect &#61; 3
期望&#96;&#96;Peer set&#96;大小为3。
[INFO] bootstrap_expect > 0: expecting 3 servers
在Raft协议初始化状态下&#xff0c;Server节点启动默认是跟随者&#xff08;follower&#xff09;状态。
[INFO] agent.server.raft: initial configuration: index&#61;0 servers&#61;[]
[INFO] agent.server.raft: entering follower state: follower&#61;"Node at 172.24.29.6:8300 [Follower]" leader&#61;
从 Consul启动完成后&#xff0c;使用配置retry_join &#61; ["172.26.4.38","172.26.4.125"]
属性&#xff0c;通过self
组件发现参与选举的节点数。当达到期望节点数后 最先超时的跟随者节点会增加自己的任期编号&#xff0c;并推举自己为候选人&#xff08;candidate&#xff09;&#xff0c;给自己投票&#xff0c;然后向其它节点发送请求投票 RPC 消息&#xff0c;请它们选举自己为领导者。
[INFO] Consul agent running! Consul Agent
[INFO] agent.server.raft: no known peers, aborting election #没有发现peer set&#xff0c;停止选举
#发现预期Peer set数目&#xff0c;尝试引导
[INFO] agent.server: Found expected number of peers, attempting bootstrap
#最先超时的节点 增加自己的任期&#xff08;term&#xff09;编号&#xff0c;推举自己为候选人&#xff0c;给自己投票
[INFO] agent.server.raft: heartbeat timeout reached, starting election: last-leader&#61;
[INFO] agent.server.raft: entering candidate state: node&#61;"Node at 172.24.29.6:8300 [Candidate]" term&#61;2
获取票数最多的节点&#xff0c;它就会成为本届任期内新的领导者。如果节点当选领导者后&#xff0c;它将周期性地发送心跳消息&#xff0c;通知其它跟随者节点不再发起选举。
[INFO] agent.server.raft: election won: tally&#61;2
[INFO] agent.server.raft: entering leader state: leader&#61;"Node at 172.24.29.6:8300 [Leader]"
开始日志复制
#已经添加Peer set中&#xff0c;开始日志复制&#xff0c;peer指向其它节点id
[INFO] agent.server.raft: added peer, starting replication: peer&#61;e6a8a239-1c5a-3a17-20ab-176fc8c5056e
[INFO] agent.server.raft: added peer, starting replication: peer&#61;b4b9fee5-54d9-0455-2cf0-dc647a3af745l
当一个RPC请求到达非Leader Server节点&#xff0c;请求就会被转发到Leader节点。请求分为两种类型&#xff1a;
FSM
&#xff0c;FSM
可以理解为有限状态机&#xff0c;有限个状态以及在这些状态之间的转移和动做等行为的数学模型。新日志的应用&#xff0c;FSM会发生状态转换&#xff0c;相同的日志序列的应用必须致使相同的状态。每一个数据中心选择独立的Leader和维护Peer set
。数据按照数据中心进行划分&#xff0c;因此每一个Leader只负责在相应数据中心的数据。
虽然全部日志副本的写入都是基于Raft&#xff0c;读取更灵活。但为了支持开发人员可能须要的各类权衡&#xff0c;Consul支持3种不一样的一致性模式。
三种读模式是&#xff1a;
Consul使用Gossip协议管理成员并向集群广播消息&#xff0c;Gossip协议是通过使用Serf
库提供的。Serf
是一个用于集群节点成员&#xff08;membership&#xff09;发现、故障检测&#xff08;failure detection&#xff09;和编排的工具组件。它是分散的、容错的和高可用性的。非常轻量级运行在内存中脚本中&#xff0c;使用UDP消息进行通信&#xff0c;它使用gossip协议。Consu屏蔽Serf
的抽象提供这些特性。Consul使用两个不同的Gossip Pool
&#xff0c;如下&#xff1a;
在Consul中&#xff0c;每个数据中心都有一个LAN Gossip Pool
&#xff0c;这里面包含这个数据中心的所有成员节点。主要作用如下:
Gossip Pool
具有可靠和快速的事件广播。在多数据中心组成服务中&#xff0c;WAN Gossip Pool
是唯一的。不同数据中心下的所有节点都参与 WAN Pool
, 该池允许服务器执行跨数据中心请求。