Consul 介绍

  • ConsulHashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。

  • 使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

Consul 基础概念

  • Agent: agent 就是实际运行的 consul 服务,启动时可选以 server 或者 client 模式运行,每个集群至少有 1 个 server,由于使用了 Raft 算法,所以对于每个集群你应该把它的 server 数设置成 3 或 5 个。
    • Server: 核心的 consul 服务,存储了所有服务注册的信息,响应查询操作,跨数据中心通信等。
    • Client: 用来在集群中每个机器上运行,进行服务注册 / 健康检查的进程。
  • Cluster: 集群,由多台共同提供服务的机器组成的集合称为集群,agent 在集群的每个成员上都要运行。
  • DataCenter: 数据中心。consul 支持跨数据中心组成集群。
  • Node: 安装了 agent,接入集群的机器称为 node。
  • Service: 你的服务,即服务注册和服务发现之类操作的对象。通过提供 config 文件或者调用 consul 的 HTTP API 来定义一个服务。

Consul 角色

client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。

server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其它数据中心通讯。 每个数据中心的 server 数量推荐为 3 个或是 5 个。

Consul 模式

  • CLIENT:表示consulclient模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。

  • SERVER:表示consulserver模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。

  • SERVER-LEADER:中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。

  • 其它信息:其它信息包括它们之间的通信方式,还有一些协议信息,算法。它们是用于保证节点之间的数据同步,实时性要求等等一系列集群问题的解决。这些有兴趣的自己看看官方文档。

Consul 基本使用

启动consul
  • 启动节点1(server模式)
    • -node:节点的名称
    • -bind:绑定的一个地址,用于节点之间通信的地址,可以是内外网,必须是可以访问到的地址
    • -server:这个就是表示这个节点是个SERVER
    • -bootstrap-expect:这个就是表示期望提供的SERVER节点数目,数目一达到,它就会被激活,然后就是LEADER了
1
consul agent -server -bind=172.17.0.2  -bootstrap-expect=3 -node=node1
  • 启动节点2-3(server模式)
    • -join:这个表示启动的时候,要加入到哪个集群内,这里就是说要加入到节点1的集群
    • -node-id:这个貌似版本8才加入的,这里用这个来指定唯一的节点ID,可以查看这个issue
    • -client:这个表示注册或者查询等一系列客户端对它操作的IP,如果不指定这个IP,默认是127.0.0.1。
1
consul agent -server -bind=172.17.0.3  -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}')  -node=node2
  • 启动节点4(client模式)

    • 除了没有-server,其它都是一样的,没有这个就说明这个节点是CLIENT
      1
      consul agent -bind=172.17.0.5 -retry-join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}')  -node=node4
  • Consul集群

    • consul members查看下集群的状态
      • 4个节点都列出来了。Status表示它们的状态,都是alive。Type表示它们的类型,三个SERVER一个CLIENT,和我们之前启动的一样。DC表示数据中心,都是dc1。
    • consul join 10.201.102.198 加入集群

  • Consul同时提供了一个漂亮的功能齐全的WEB界面,开箱即用.界面可以用来查看所有的节点,可以查看健康检查和他们的当前状态.可以读取和设置K/V 存储的数据,启动完成之后就可以使用http://127.0.0.1:8500来查询服务状态,有界面查看还是挺人性化的
  • 节点异常consul的处理
    • LEADER 挂了
      • leader挂了,consul会重新选取出新的leader,只要超过一半的SERVER还活着,集群是可以正常工作的。node1是leader,所以把这个容器停了。
      • 日志打印,心跳检查node1的ip超时,接着开始选举。node2被选举为新的leader
使用consul
  • 操作 ConsulCommandsRESTful HTTP API 两种方式,具体详情可以到官网API链接里查看,使用起来十分方便

  • 注册服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUT http://127.0.0.1:8500/v1/agent/service/register

{
"ID": "userServiceId1", //服务id
"Name": "userServiceName1", //服务名
"Tags": [ //服务的tag,自定义,可以根据这个tag来区分同一个服务名的服务
"userService1",
"v1"
],
"Address": "127.0.0.1",//服务注册到consul的IP,服务发现,发现的就是这个IP
"Port": 8000, //服务注册consul的PORT,发现的就是这个PORT
"EnableTagOverride": false,
"Check": { //健康检查部分
"DeregisterCriticalServiceAfter": "90m",
"HTTP": "http://www.baidu.com", //指定健康检查的URL,调用后只要返回20X,consul都认为是健康的
"Interval": "10s" //健康检查间隔时间,每隔10s,调用一次上面的URL
}
}
  • 下架服务

Sample Request

1
PUT  http://127.0.0.1:8500/v1/catalog/service/{serviceId}

Sample Response

1
status 200 ok
  • 查看所有的服务

Sample Request

1
GET http://127.0.0.1:8500/v1/agent/services

Sample Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
"userServiceId1": {
"Kind": "",
"ID": "userServiceId1",
"Service": "userServiceName1",
"Tags": [
"userService1",
"v1"
],
"Meta": {},
"Port": 8001,
"Address": "127.0.0.1",
"EnableTagOverride": false,
"CreateIndex": 0,
"ModifyIndex": 0,
"ProxyDestination": "",
"Connect": null
},
"userServiceId2": {
"Kind": "",
"ID": "userServiceId2",
"Service": "userServiceName2",
"Tags": [
"userService2",
"v1"
],
"Meta": {},
"Port": 8001,
"Address": "127.0.0.1",
"EnableTagOverride": false,
"CreateIndex": 0,
"ModifyIndex": 0,
"ProxyDestination": "",
"Connect": null
},
"userServiceId3": {
"Kind": "",
"ID": "userServiceId3",
"Service": "userServiceName3",
"Tags": [
"userService3",
"v1"
],
"Meta": {},
"Port": 8001,
"Address": "127.0.0.1",
"EnableTagOverride": false,
"CreateIndex": 0,
"ModifyIndex": 0,
"ProxyDestination": "",
"Connect": null
}
}
  • 查看某个服务

Sample Request

1
GET  http://127.0.0.1:8500/v1/catalog/service/{serviceName}

Sample Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[
{
"ID": "3c1b78a3-701a-2625-f617-94cade896b47",
"Node": "DESKTOP-DT6DIHG",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"wan": "127.0.0.1"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "userServiceId1",
"ServiceName": "userServiceName1",
"ServiceTags": [
"userService1",
"v1"
],
"ServiceAddress": "127.0.0.1",
"ServiceMeta": {},
"ServicePort": 8001,
"ServiceEnableTagOverride": false,
"ServiceProxyDestination": "",
"ServiceConnect": {
"Native": false,
"Proxy": null
},
"CreateIndex": 3220,
"ModifyIndex": 3220
}
]
  • KV Store 存值

  • 列出所有节点

1
GET http://consul.rocks/v1/catelog/nodes

Consul 工作原理

logo
logo
  • 1、当 Producer 启动的时候,会向 Consul 发送一个 post 请求,告诉 Consul 自己的 IPPort
  • 2、Consul 接收到 Producer 的注册后,每隔10s(默认)会向 Producer 发送一个健康检查的请求,检验Producer是否健康
  • 3、当 Consumer 发送 GET 方式请求 /api/addressProducer 时,会先从 Consul 中拿到一个存储服务 IPPort 的临时表,从表中拿到 ProducerIPPort 后再发送 GET 方式请求 /api/address
  • 4、该临时表每隔10s会更新,只包含有通过了健康检查的 Producer

Consul 的优势

  • 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft
  • 支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等。zookeeperetcd 均不提供多数据中心功能的支持。
  • 支持健康检查。 etcd 不提供此功能。
  • 支持 httpdns 协议接口。 zookeeper 的集成较为复杂, etcd 只支持 http 协议。
  • 官方提供 web 管理界面, etcd 无此功能。
  • 综合比较, Consul 作为服务注册和配置管理的新星, 比较值得关注和研究。

其他

  • consul 默认使用下列端口
    • 8300(tcp): Server RPC,server 用于接受其他 agent 的请求
    • 8301(tcp,udp): Serf LAN,数据中心内 gossip 交换数据用
    • 8302(tcp,udp): Serf WAN,跨数据中心 gossip 交换数据用
    • 8400(tcp): CLI RPC,接受命令行的 RPC 调用
    • 8500(tcp): HTTP API 及 Web UI
    • 8600(tcp udp): DNS 服务,可以把它配置到 53 端口来响应 dns 请求
  • 测试开发环境下可以使用consul agent -dev来启动consul,该模式下(该节点的启动不能用于生产环境,因为该模式下不会持久化任何状态),该启动模式仅仅是为了快速便捷的启动单节点consul,该节点处于server模式且是leader

参考