Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。它具有很多优点。包括:基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN(广域网) 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows。
consul是使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。
raft(分布式一致性协议):见《一致性算法之:Raft》
@client
CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。
@server
SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。
@server-leader
中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。
@raft
server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是taft。
@服务发现协议
consul采用http和dns协议,etcd只支持http
@服务注册
consul支持两种方式实现服务注册,一种是通过consul的服务注册http API,由服务自己调用API实现注册,另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。consul官方建议使用第二种方式。
@服务发现
consul支持两种方式实现服务发现,一种是通过http API来查询有哪些服务,另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。
@服务间的通信协议
Consul使用gossip协议管理成员关系、广播消息到整个集群,他有两个gossip pool(LAN pool和WAN pool),LAN pool是同一个数据中心内部通信的,WAN pool是多个数据中心通信的,LAN pool有多个,WAN pool只有一个。
一、基本概念
在描述架构之前,这里提供了一些术语来帮助声明正在探讨的东西:
- Agent——agent是一直运行在Consul集群中每个成员上的守护进程。通过运行 consul agent 来启动。agent可以运行在client或者server模式。指定节点作为client或者server是非常简单的,除非有其他agent实例。所有的agent都能运行DNS或者HTTP接口,并负责运行时检查和保持服务同步。
- Client——一个Client是一个转发所有RPC到server的代理。这个client是相对无状态的。client唯一执行的后台活动是加入LAN gossip池。这有一个最低的资源开销并且仅消耗少量的网络带宽。
- Server——一个server是一个有一组扩展功能的代理,这些功能包括参与Raft选举,维护集群状态,响应RPC查询,与其他数据中心交互WAN gossip和转发查询给leader或者远程数据中心。
- DataCenter——虽然数据中心的定义是显而易见的,但是有一些细微的细节必须考虑。例如,在EC2中,多个可用区域被认为组成一个数据中心?我们定义数据中心为一个私有的,低延迟和高带宽的一个网络环境。这不包括访问公共网络,但是对于我们而言,同一个EC2中的多个可用区域可以被认为是一个数据中心的一部分。
- Consensus——在我们的文档中,我们使用Consensus来表明就leader选举和事务的顺序达成一致。由于这些事务都被应用到有限状态机上,Consensus暗示复制状态机的一致性。
- Gossip——Consul建立在Serf的基础之上,它提供了一个用于多播目的的完整的gossip协议。Serf提供成员关系,故障检测和事件广播。更多的信息在gossip文档中描述。这足以知道gossip使用基于UDP的随机的点到点通信。
- LAN Gossip——它包含所有位于同一个局域网或者数据中心的所有节点。
- WAN Gossip——它只包含Server。这些server主要分布在不同的数据中心并且通常通过因特网或者广域网通信。
- RPC——远程过程调用。这是一个允许client请求server的请求/响应机制。
从10000万英尺的高度看consul架构:
拆解开这个体系,从每一个组件开始了解。首先,可以看到有两个数据中心,分别标记为“one”和“two”。Consul是支持多数据中心一流,并且是常用业务场景。
每个数据中心都是由Server和client组成。建议有3~5 Server——基于故障处理和性能的平衡之策。如果增加越多的机器,则Consensus会越来越慢。对client没有限制,可以很容易地扩展到成千上万或数万。
同一个数据中心的所有节点都要加入Gossip协议。这意味着gossip pool包含给定数据中心的所有节点。有以下目的:首先,没有必要为client配置服务器地址参数;发现是自动完成的。第二,节点故障检测的工作不是放置在服务器上,而是分布式的。这使故障检测比心跳机制更可扩展性。第三,可用来作为消息层通知重要的事件,如leader选举。
每个数据中心的服务器都是属于一个Raft peer。这意味着,他们一起工作,选出一个的Leader,Leader server是有额外的职责。负责处理所有的查询和事务。事务也必须通过Consensus协议复制到所有的伙伴。由于这一要求,当非Leader Server接收到一个RPC请求,会转发到集群的leader。
Server节点也是作为WAN gossip pool的一部分。这个pool是与LAN gossip pool是不同的,它为具有更高延迟的网络响应做了优化,并且可能包括其他consul集群的server节点。设计WANpool的目的是让数据中心能够以low-touch的方式发现彼此。将一个新的数据中心加入现有的WAN Gossip是很容易的。因为池中的所有Server都是可控制的,这也使跨数据中心的要求。当一个Serfer接收到不同的数据中心的要求时,它把这个请求转发给相应数据中心的任一Server。然后,接收到请求的Server可能会转发给Leader。
多个数据中心之间是低耦合,但由于故障检测、连接缓存复用、跨数据中心要求快速和可靠的响应。
二、consul安装
1、到consul的官网下载:https://www.consul.io/downloads.html
2、解压
3、启动
consul agent -dev
指定ip:
consul agent -dev -client 10.200.110.100 -ui
D:\workspace\service-producter\build\libs>java -Dserver.port=9999 -Dspring.cloud.consul.host=10.200.110.100 -Dspring.cloud.consul.discovery.hostname=10.200.110.100 -jar service-producter-201810241824.jar
Consul 启动参数说明
启动参数 | 说明 |
---|---|
-advertise | 通知展现地址用来改变我们给集群中的其他节点展现的地址,一般情况下-bind地址就是展现地址 |
-bootstrap | 用来控制一个server是否在bootstrap模式,在一个datacenter中只能有一个server处于bootstrap模式,当一个server处于bootstrap模式时,可以自己选举为raft leader |
-bootstrap-expect | 在一个datacenter中期望提供的server节点数目,当该值提供的时候,consul一直等到达到指定sever数目的时候才会引导整个集群,该标记不能和bootstrap公用 |
-bind | 该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0 |
-client | consul绑定在哪个client地址上,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1 |
-config-file | 明确的指定要加载哪个配置文件 |
-config-dir | 配置文件目录,里面所有以.json结尾的文件都会被加载 |
-data-dir | 提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在 |
-dc | 该标记控制agent允许的datacenter的名称,默认是dc1 |
-encrypt | 指定secret key,使consul在通讯时进行加密,key可以通过consul keygen生成,同一个集群中的节点必须使用相同的key |
-join | 加入一个已经启动的agent的ip地址,可以多次指定多个agent的地址。如果consul不能加入任何指定的地址中,则agent会启动失败,默认agent启动时不会加入任何节点。 |
-retry-join | 和join类似,但是允许你在第一次失败后进行尝试 |
-retry-interval | 两次join之间的时间间隔,默认是30s |
-retry-max | 尝试重复join的次数,默认是0,也就是无限次尝试 |
-log-level | consul agent启动后显示的日志信息级别。默认是info,可选:trace、debug、info、warn、err |
-node | 节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名 |
-protocol | consul使用的协议版本 |
-rejoin | 使consul忽略先前的离开,在再次启动后仍旧尝试加入集群中 |
-server | 定义agent运行在server模式,每个集群至少有一个server,建议每个集群的server不要超过5个 |
-syslog | 开启系统日志功能,只在linux/osx上生效 |
-ui | 使用自带的ui |
-ui-dir | 提供存放web ui资源的路径,该目录必须是可读的 |
-pid-file | 提供一个路径来存放pid文件,可以使用该文件进行SIGINT/SIGHUP(关闭/更新)agent |
4、验证
用浏览器访问:http://localhost:8500/ui/#/dc1/services
其它机器如果要访问,则需要加-client参数
更多参数说明如下:
server 表示启动的为consul server ,构建一个consul cluster 一般建议使用3或者5个consul server bootstrap-expect 1 表示期望的服务节点数目为1 -data-dir 数据目录,如果该文件夹不存在则手工创建,如果在consul发生错误后,建议先清理该目录文件 advertise 设置广播地址,ip可以设置为公网ip client 设置client访问的地址 ui-dir web控制台目录位置
三、consul功能介绍
consul 具有以下性质:
- service discovery(服务发现):consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册。
- health checking(服务健康监测):健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面。
- key/value storage(ey/value 存储):一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
- multi-datacenter(多数据中心):无需复杂的配置,即可支持任意数量的区域。
consul可运行在mac windows Linux 等机器上。
四、RedHat7.2上安装Consul
1. VM@aws info
[root@ip-172-30-0-43home]# uname -a
Linuxip-172-30-0-43.ec2.internal 3.10.0-327.el7.x86_64 #1 SMP Thu Oct 2917:29:29 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
[root@ip-172-30-0-43home]# cat /etc/redhat-release
RedHat Enterprise Linux Server release 7.2 (Maipo)
2. 安装
主页https://www.consul.io/
当然 版本
https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
下载, 然后unzip 解压, 得到唯一个可执行文件
wgethttps://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
unzipconsul_0.6.4_linux_amd64.zip
检查一下版本
[root@ip-172-30-0-43consul]# ./consul version
Consulv0.6.4
ConsulProtocol: 3 (Understands back to: 1)
[root@ip-172-30-0-43consul]#
3. 以Bootstrap Server 模式 启动
./consulagent -server -bootstrap-expect=1 -data-dir /tmp/consul
./consulagent -server -bootstrap -data-dir /tmp/consul
输出如下:
[root@ip-172-30-0-43consul]# ./consul agent -server -bootstrap-expect=1 -data-dir/tmp/consul
==>WARNING: BootstrapExpect Mode is specified as 1; this is the same asBootstrap mode.
==>WARNING: Bootstrap mode enabled! Do not enable unless necessary
==>Starting Consul agent...
==>Starting Consul agent RPC...
==>Consul agent running!
Nodename: 'ip-172-30-0-43.ec2.internal'
Datacenter:'dc1'
Server:true (bootstrap: true)
ClientAddr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
ClusterAddr: 172.30.0.43 (LAN: 8301, WAN: 8302)
Gossipencrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas:<disabled>
......(省略)......
4. 查看,成员info等
[root@ip-172-30-0-43consul]# ./consul members
Node Address Status Type Build Protocol DC
ip-172-30-0-43.ec2.internal 172.30.0.43:8301 alive server 0.6.4 2 dc1
[root@ip-172-30-0-43consul]# ./consul members -detailed
Node Address Status Tags
ip-172-30-0-43.ec2.internal 172.30.0.43:8301 alive bootstrap=1,build=0.6.4:26a0ef8c,dc=dc1,port=8300,role=consul,vsn=2,vsn_max=3,vsn_min=1
[root@ip-172-30-0-43consul]# ./consul info
agent:
check_monitors= 0
check_ttls= 0
checks= 0
services= 1
build:
......(省略)......
二)服务的注册与发现
1. 节点的基本情况
两台Node:
ip-172-30-0-43 RedHat7.2 172.30.0.43Server
ip-172-30-0-89 Amazon(4.1.10)172.30.0.89 Server
2. 运行的主要命令
参数-bootstrap-expect=2指明 是两台server
/home/consul/consulagent -server -bootstrap-expect=2 -data-dir /tmp/consul-node=ip-172-30-0-43 -bind=172.30.0.43 -dc=dc1
/home/consul/consulagent -server -bootstrap-expect=2 -data-dir /tmp/consul-node=ip-172-30-0-89 -bind=172.30.0.89 -dc=dc1
/home/consul/consuljoin 172.30.0.89
3. 控制台输出
[root@ip-172-30-0-43tmp]# /home/consul/consul agent -server -bootstrap-expect=2 -data-dir/tmp/consul -node=ip-172-30-0-43 -bind=172.30.0.43 -dc=dc1
==>WARNING: Expect Mode enabled, expecting 2 servers
==>Starting Consul agent...
==>Starting Consul agent RPC...
==>Consul agent running!
Nodename: 'ip-172-30-0-43'
Datacenter:'dc1'
Server:true (bootstrap: false)
ClientAddr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
ClusterAddr: 172.30.0.43 (LAN: 8301, WAN: 8302)
Gossipencrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas:<disabled>
==>Log data will now stream in as it occurs:
2016/05/1601:48:46 [INFO] serf: EventMemberJoin: ip-172-30-0-43 172.30.0.43
2016/05/1601:48:46 [INFO] serf: EventMemberJoin: ip-172-30-0-43.dc1 172.30.0.43
2016/05/1601:48:46 [INFO] raft: Node at 172.30.0.43:8300 [Follower] enteringFollower state
2016/05/1601:48:46 [INFO] consul: adding LAN server ip-172-30-0-43 (Addr:172.30.0.43:8300) (DC: dc1)
2016/05/1601:48:46 [INFO] consul: adding WAN server ip-172-30-0-43.dc1 (Addr:172.30.0.43:8300) (DC: dc1)
2016/05/1601:48:46 [ERR] agent: failed to sync remote state: No cluster leader
2016/05/1601:48:47 [WARN] raft: EnableSingleNode disabled, and no known peers.Aborting election.
2016/05/1601:48:56 [INFO] agent.rpc: Accepted client: 127.0.0.1:41616
2016/05/1601:48:56 [INFO] agent: (LAN) joining: [172.30.0.89]
2016/05/1601:48:56 [INFO] serf: EventMemberJoin: ip-172-30-0-89 172.30.0.89
2016/05/1601:48:56 [INFO] agent: (LAN) joined: 1 Err: <nil>
2016/05/1601:48:56 [INFO] consul: adding LAN server ip-172-30-0-89 (Addr:172.30.0.89:8300) (DC: dc1)
2016/05/1601:48:56 [INFO] consul: Attempting bootstrap with nodes:[172.30.0.43:8300 172.30.0.89:8300]
2016/05/1601:48:57 [INFO] consul: New leader elected: ip-172-30-0-89
2016/05/1601:49:00 [INFO] agent: Synced service 'consul'
[root@ip-172-30-0-89tmp]# /home/consul/consul agent -server -bootstrap-expect=2 -data-dir/tmp/consul -node=ip-172-30-0-89 -bind=172.30.0.89 -dc=dc1
==>WARNING: Expect Mode enabled, expecting 2 servers
==>Starting Consul agent...
==>Starting Consul agent RPC...
==>Consul agent running!
Nodename: 'ip-172-30-0-89'
Datacenter:'dc1'
Server:true (bootstrap: false)
ClientAddr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
ClusterAddr: 172.30.0.89 (LAN: 8301, WAN: 8302)
Gossipencrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas:<disabled>
==>Log data will now stream in as it occurs:
2016/05/1605:48:50 [INFO] serf: EventMemberJoin: ip-172-30-0-89 172.30.0.89
2016/05/1605:48:50 [INFO] serf: EventMemberJoin: ip-172-30-0-89.dc1 172.30.0.89
2016/05/1605:48:50 [INFO] raft: Node at 172.30.0.89:8300 [Follower] enteringFollower state
2016/05/1605:48:50 [INFO] consul: adding LAN server ip-172-30-0-89 (Addr:172.30.0.89:8300) (DC: dc1)
2016/05/1605:48:50 [INFO] consul: adding WAN server ip-172-30-0-89.dc1 (Addr:172.30.0.89:8300) (DC: dc1)
2016/05/1605:48:50 [ERR] agent: failed to sync remote state: No cluster leader
2016/05/1605:48:51 [WARN] raft: EnableSingleNode disabled, and no known peers.Aborting election.
2016/05/1605:48:56 [INFO] serf: EventMemberJoin: ip-172-30-0-43 172.30.0.43
2016/05/1605:48:56 [INFO] consul: adding LAN server ip-172-30-0-43 (Addr:172.30.0.43:8300) (DC: dc1)
2016/05/1605:48:56 [INFO] consul: Attempting bootstrap with nodes:[172.30.0.89:8300 172.30.0.43:8300]
2016/05/1605:48:57 [WARN] raft: Heartbeat timeout reached, starting election
2016/05/1605:48:57 [INFO] raft: Node at 172.30.0.89:8300 [Candidate] enteringCandidate state
2016/05/1605:48:57 [INFO] raft: Election won. Tally: 2
2016/05/1605:48:57 [INFO] raft: Node at 172.30.0.89:8300 [Leader] enteringLeader state
2016/05/1605:48:57 [INFO] consul: cluster leadership acquired
2016/05/1605:48:57 [INFO] consul: New leader elected: ip-172-30-0-89
2016/05/1605:48:57 [INFO] raft: pipelining replication to peer 172.30.0.43:8300
2016/05/1605:48:57 [INFO] consul: member 'ip-172-30-0-89' joined, markinghealth alive
2016/05/1605:48:57 [INFO] consul: member 'ip-172-30-0-43' joined, markinghealth alive
2016/05/1605:48:59 [INFO] agent: Synced service 'consul'
[root@ip-172-30-0-43~]# /home/consul/consul join 172.30.0.89
Successfullyjoined cluster by contacting 1 nodes.
[root@ip-172-30-0-43~]# /home/consul/consul members
Node Address Status Type Build Protocol DC
ip-172-30-0-43 172.30.0.43:8301 alive server 0.6.4 2 dc1
ip-172-30-0-89 172.30.0.89:8301 alive server 0.6.4 2 dc1
[root@ip-172-30-0-43~]# tree /tmp/consul/
/tmp/consul/
├── checkpoint-signature
├── raft
│ ├── peers.json
│ ├── raft.db
│ └── snapshots
└── serf
├── local.snapshot
└── remote.snapshot
3 directories, 5 files
输入Ctrl+ C 后,停止服务, 输出如下:
^C==>Caught signal: interrupt
==>Gracefully shutting down agent...
2016/05/1603:03:30 [INFO] consul: server starting leave
2016/05/1603:03:30 [INFO] serf: EventMemberLeave: ip-172-30-0-43.dc1172.30.0.43
2016/05/1603:03:30 [INFO] consul: removing WAN server ip-172-30-0-43.dc1 (Addr:172.30.0.43:8300) (DC: dc1)
2016/05/1603:03:31 [INFO] serf: EventMemberLeave: ip-172-30-0-43 172.30.0.43
2016/05/1603:03:31 [INFO] consul: removing LAN server ip-172-30-0-43 (Addr:172.30.0.43:8300) (DC: dc1)
2016/05/1603:03:31 [INFO] raft: Removed ourself, transitioning to follower
2016/05/1603:03:32 [INFO] agent: requesting shutdown
2016/05/1603:03:32 [INFO] consul: shutting down server
2016/05/1603:03:32 [ERR] dns: error starting tcp server: accept tcp127.0.0.1:8600: use of closed network connection
2016/05/1603:03:32 [INFO] agent: shutdown complete
4. 存储值
利用打开的8500http服务,存储某些值。
[root@ip-172-30-0-43tmp]# curl -X PUT -d 'bar'http://localhost:8500/v1/kv/foo
true[root@ip-172-30-0-43tmp]#
[root@ip-172-30-0-43tmp]# curlhttp://localhost:8500/v1/kv/foo
[{"LockIndex":0,"Key":"foo","Flags":0,"Value":"YmFy","CreateIndex":144,"ModifyIndex":144}][root@ip-172-30-0-43tmp]#
[root@ip-172-30-0-43tmp]# echo "YmFy" | base64 --decode
bar[root@ip-172-30-0-43tmp]#
5. 其他
重启,但加上-rejoin命令:
如:
/home/consul/consulagent -server -bootstrap-expect=2 -data-dir /tmp/consul-node=ip-172-30-0-43 -bind=172.30.0.43 -dc=dc1 -rejoin
退出, 使用consul leave 命令
五、consul高可用集群安装
本文就是介绍如何搭建一个3节点的Consul集群:
1. 准备工作
a) 启动三台虚拟机
s1:10.0.0.5
s2:10..0.0.6
s3:10..0.0.7
b) 每台机器上在 /usr/local 新建文件夹
mkdir
–p /usr/local/consul/data
c) 下载consul,并将其考入到/usr/local/consul中
下载地址:https://www.consul.io/downloads.html
sudo wget https://releases.hashicorp.com/consul/0.7.2/consul_0.7.2_linux_amd64.zip
unzip consul_0.7.2_linux_amd64.zip
2. 启动server agent
a) 进入consul目录中
b) 执行命令:
sudo ./consul agent -server -bootstrap-expect 2 -data-dir=data -node=n1 -bind=10.0.0.5 -client=0.0.0.0 &
注:
i. server: 以server身份启动。
ii. bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。
iii. data-dir:data存放的目录,更多信息请参阅consul数据同步机制
iv. node:节点id,在同一集群不能重复。
v. bind:监听的ip地址。
vi. client 客户端的ip地址
vii. & :在后台运行,此为linux脚本语法
vii. 更多参数及配置说明见consul官方说明文档https://www.consul.io/docs/agent/options.html。
c) 修改node和bind信息,分别在另外两台机器中执行 上面命令。
sudo ./consul agent -server -bootstrap-expect 2 -data-dir=data -node=n2 -bind=10.0.0.6 -client=0.0.0.0 &
sudo ./consul agent -server -bootstrap-expect 2 -data-dir=data -node=n3 -bind=10.0.0.5 -client=0.0.0.0 &
d) 在s2、s3中分别执行:
.
/consul
join
10.0.0.7
到这里整个consul server 集群就算完成了,可以利用consul members查看集群中包含的node信息。使用consul info命令可以查看当前节点状态,包括是否在集群中,是否为leader(主)。
3. 搭建管理工具
consul自带的WEB UI,Web ui是consul提供的可视化的服务web界面,可以对key/value和服务、节点进行操作
a) 下载consul web ui(包含一个html和一个static文件件),和本机中的consul放到同级目录。
b) 在本机启动consul,需要设置-ui-dir ./webui
sudo ./consul agent -server -bootstrap-expect 2 -data-dir=data -node=n3 -bind=10.0.0.7 -ui-dir=webui -client 0.0.0.0 &
打开浏览器访问8500 端口: