在传统的单体架构下不够灵活不能很好的适应变化,从而向微服务架构进行转换,而伴随着大量服务的出现,管理运维十分不便,于是开始搞一些自动化的策略,服务发现应运而生。所以如果需要使用服务发现,应该了解服务治理的痛点。
介绍
Consul 是 HashiCorp 公司的一个开源的服务注册与发现工具,具有分布式、高可用性、可横向扩展、多数据中心的服务发现和配置共享的服务软件。Consul 官网目前主要推荐在服务网格中的使用。
与其它分布式服务注册与发现的方案相比,Consul 的方案是“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具。Consul使用 Go 语言开发,具有跨平台、运行高效等特点,也便于和 Docker 配合使用。
特性
Service Discovery: 服务注册与发现,Consul 的客户端可以做为一个服务注册到 Consul,也可以通过 Consul 来查找特定的服务提供者,并且根据提供的信息进行调用。
Health Checking: Consul 客户端会定期(默认10s)发送一次健康检查和服务端进行通讯,判断客户端的状态、内存使用情况是否正常,用来监控整个集群的状态,防止服务转发到故障的服务。
KV Store: Consul 提供了一个便捷的键值存储。可以用来保持动态配置、协助服务、建立 Leader 选举,及开发者想构造的其它一些事务。
Secure Service Communication: Consul 可以为服务生成分布式的 TLS 证书,以建立相互的 TLS 连接。 可使用 intentions 定义允许哪些服务进行通信。可以使用 intentions 轻松管理服务隔离,而不是复杂的网络拓扑和静态防火墙规则。
Multi Datacenter: Consul 支持开箱即用的多数据中心,这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。
Consul 角色
优势
使用 Raft 算法来保证一致性,比复杂的 Paxos 算法更直接。相比较而言 zookeeper 采用的是 Paxos,而 etcd 使用的则是 Raft。
支持多数据中心,内外网的服务采用不同的端口进行监听。多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟、分片等情况。 zookeeper 和 etcd 均不提供多数据中心功能的支持。
支持健康检查。etcd 不支持。
支持 HTTP 和 DNS 协议接口。 zookeeper 的集成较为复杂,etcd 只支持 HTTP 协议。
支持 Web 管理界面。etcd 不支持。
保持了 CAP 中的 CP,保持了强一致性和分区容错性。
支持 HTTP\gRPC\DNS 多种访问方式。
对比
名称 | 优点 | 缺点 | 接口 | 一致性算法 |
zookeeper | 功能强大,不仅仅只是服务发现 提供 watcher 机制能实时获取服务提供者的状态 dubbo 等框架支持
| 没有健康检查 需在服务中集成 sdk,复杂度高 不支持多数据中
| sdk | Paxos |
consul | 简单易用,不需要集成 sdk 自带健康检查 支持多数据中心 提供 web 管理界面
| 不能实时获取服务信息的变化通知 | http/dns | Raft |
etcd | 简单易用,不需要集成 sdk 可配置性强
| 没有健康检查 需配合第三方工具一起完成服务发现 不支持多数据中心
| http | Raft |
架构
图上 datacenter 分成上下两个部分,这两个部分不是完全隔离的。他们之间通过 WAN GOSSIP 进行报文交互。
单个 datacenter 中,节点被划分成两种颜色,红色的 Server,紫色的 Client, 他们之间通过 GRPC 进行通信(业务数据),除此之外 Client 和 Server 之间通过一条 LAN Gosssip(流言协议) 进行通信,如当 Server 节点增加或者 down 机后 Client 可以获取对应的 Server 列表去除或者增加 Server 列表。
同一个 Consul agent 程序启动的时候,通过制定不同的参数来运行 Server 和 Client 模式。也就是说 Client 和 Server 本质上都是 Client Agent。
Server 节点有一个 Leader 和多个 Follower,Leader 节点会将数据同步到 Follower,Server 的数量推荐是3个或者5个,在 Leader挂掉的时候会启动选举机制产生一个新的 Leader。
Gossip:
Gossip protocol 也叫 Epidemic Protocol (流行病协议),还有很多别名,比如:“流言算法”、“疫情传播算法”等。
Consensus:
使用 Consensus 来表明 leader 选举和事务的顺序达成一致。为了以容错方式达成一致,一般有超过半数一致则可以认为整体一致。Consul 使用 Raft 实现一致性,进行 leader 选举,在 Consul 中的使用 bootstrap 时,可以进行自选,其他 Server 加入进来后 bootstrap 就可以取消。
LAN Gossip:
包含所有位于同一个局域网或者数据中心的所有节点。
WAN Gossip:
只包含 Server,这些 Server 主要分布在不同的数据中心并且通常通过因特网或者广域网通信。
gRPC:
远程过程调用,Client 请求 Server 的请求/响应机制。
Server:
参与共识仲裁(raft)
存储机器状态(日志存储)
处理查询
维护周边(LAN/WAN) 节点之间的关系
Client :
核心:
模式
端口说明
常用命令
agent:运行一个consul agent
consul agent -dev
join:将agent加入到consul集群
consul join IP
members:列出consul cluster集群中的members
consul members
leave将节点移除所在集群
consul leave
Consul Agent
安装
访问 Consul 官网 下载 Consul 的最新版本,根据不同的系统类型选择不同的安装包。
单机
wget https://releases.hashicorp.com/consul/1.12.5/consul_1.12.5_linux_amd64.zip
unzip consul_1.12.5_linux_amd64.zip
# -dev表示开发模式运行,另外还有-server表示服务模式运行
./consul agent -dev -client=0.0.0.0 -node=node1
集群
名称 | IP
| 角色 |
node1 | 192.168.7.101 | server |
node2 | 192.168.7.102 | server |
node3 | 192.168.7.103 | server |
client1 | 192.168.8.100 | client |
启动
在生产环境中推荐使用json或hcl格式的配置文件进行启动,配置文件提供了某些命令行无法提供的参数和功能,如开启prometheus监控等。
tree -C -L 1 /data/consul/
/data/consul
├── bin
├── conf
├── consul.d
├── data
├── logs
└── snapshot
# 命令行方式
# node1
./consul agent -server -bind=192.168.7.101 -client=0.0.0.0 -ui -bootstrap-expect=3 \
-data-dir=/data/consul/data -node=node1
# node2
./consul agent -server -bind=192.168.7.102 -client=0.0.0.0 -ui -bootstrap-expect=3 \
-data-dir=/data/consul/data -node=node2
./consul join 192.168.7.101
# node3
./consul agent -server -bind=192.168.7.103 -client=0.0.0.0 -ui -bootstrap-expect=3 \
-data-dir=/data/consul/data -node=node3
./consul join 192.168.7.101
# client1
./consul agent -client=0.0.0.0 -bind=192.168.8.100 -data-dir=/data/consul/data \
-node=client1
./consul join 192.168.7.101
# 配置文件方式参考
cat ./conf/consul.hcl
datacenter = "outside"
data_dir = "/data/consul/data"
server = true
bootstrap_expect = 1
bind_addr = "127.0.0.1"
client_addr = "0.0.0.0"
ui_config {
enabled = true
}
node_name = "node1"
bootstrap_expect = 3
connect {
enabled = false
}
acl = {
enabled = true
default_policy = "deny"
enable_token_persistence = true
tokens = {
agent = "023a6a81-dd6f-5b22-b0f2-0f7da6fda489"
}
}
# 启动
./consul agent -config-dir=./conf
Systemd配置
cat /usr/lib/systemd/system/consul.service
[Unit]
Description=consul server daemon
Documentation=https://www.consul.io/docs/index.html
After=network.target
[Service]
ExecStart=/data/consul/bin/consul agent -config-dir=/data/consul/conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
# 启动
systemctl daemon-reload
systemctl start consul
systemctl enable consul
systemctl status consul
配置文件模板
cat consul.json.example
{
"datacenter": "dc1",
"client_addr": "0.0.0.0",
"bind_addr": "{{ GetInterfaceIP \"eth0\" }}",
"data_dir": "/data/consul",
"retry_interval": "20s",
"retry_join": ["1.1.1.1","2.2.2.2"],
"enable_local_script_checks": true,
"log_file": "/data/consul/logs",
"log_level": "info",
"pid_file": "/data/consul/run/consul.pid",
"performance": {
"raft_multiplier": 1
},
"telemetry": {
"prometheus_retention_time": "120s",
"disable_hostname": true
}
}
cat consul.server.json.example
{
"node_name": "node1",
"bootstrap_expect": 3,
"server": true,
"ui": true
}
cat consul.hcl.example
datacenter = "dc1"
bind_addr = "{{ GetInterfaceIP \"eth0\" }}"
client_addr = "0.0.0.0"
data_dir = "/data/consul"
retry_interval = "20s"
retry_join = ["1.1.1.1","2.2.2.2"]
enable_local_script_checks = true
log_file = "/data/consul/logs"
pid_file = "/data/consul/run/consul.pid"
log_level = "info"
performance {
raft_multiplier = 1
}
telemetry {
prometheus_retention_time = "120s"
disable_hostname = true
}
cat consul.server.hcl.example
node_name = "node1"
bootstrap_expect = 3
server = true
ui = true
备份
快照的备份防集群数据丢失时用快照数据进行还原
./consul snapshot save ./snapshot
访问
http://192.168.7.101:8500
参考:
https://developer.hashicorp.com/consul/docs
https://www.cnblogs.com/wangguishe/p/15599233.html
https://blog.51cto.com/shmilyjinian/2512077