1. 概述

1.1 什么是consul

Consul 是 HashiCorp 公司推出的开源工具,使用go语言开发,可用于实现分布式系统的服务发现与配置。 Consul内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。Consul 是分布式的、高可用的、 可横向扩展的。

  • 服务发现: Consul 提供了通过 DNS 或者 HTTP 接口的方式来注册服务和发现服务。一些外部的服务通过 Consul 很容易的找到它所依赖的服务。
  • 健康检查: Consul的客户端可以通过多种方式来检查某个服务或当前节点是否处于健康状态,比如查看一个服务是否可以返回200 OK,或者是查看client当前部署的机器的内存使用是否在80%以下。利用健康检查可用来避免流量被转发到有故障的服务上。
  • Key/Value存储: 应用程序可以根据自己的需要使用 Consul 提供的 Key/Value 存储。 Consul 提供了简单易用的 HTTP 接口,结合其他工具可以实现动态配置、功能标记、领袖选举等等功能。
  • 多数据中心: Consul 支持开箱即用的多数据中心. 这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。

1.2 与其他框架对比

FeatureConsulzookeeperetcdeuerka
服务健康检查服务状态,内存,硬盘等(弱)长连接,keepalive连接心跳可配支持
多数据中心支持
kv存储服务支持支持支持
一致性raftpaxosraft
capcpcpcpap
使用接口支持http和dns客户端http/grpchttp(sidecar)
watch支持全量/支持long polling支持支持 long polling支持 long polling
自身监控metricsmetricsmetrics
安全acl/httpsaclhttps支持(弱)-
spring cloud集成已支持已支持已支持已支持

注:

  1. 轻松理解CAP理论

1.3 术语

词汇说明
Agentagent是一直运行在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暗示复制状态机的一致性。
GossipConsul建立在Serf的基础之上,它提供了一个用于多播目的的完整的gossip协议。Serf提供成员关系,故障检测和事件广播。更多的信息在gossip文档中描述。这足以知道g ossip使用基于UDP的随机的点到点通信。
LAN Gossip它包含所有位于同一个局域网或者数据中心的所有节点。
WAN Gossip它只包含Server。这些server主要分布在不同的数据中心并且通常通过因特网或者广域网通信。
RPC远程过程调用。这是一个允许client请求server的请求/响应机制。

1.4 consul默认端口

Consul最多需要6个不同的端口才能正常工作,有些使用TCP,UDP或两种协议。 主要端口说明如下:

角色端口号协议功能
server8300TCPagent server 使用的,用于处理其他agent发来的请求
serf_lan8301TCP 、UDPagent使用此端口处理LAN中的gossip(用于单个数据中心)
serf_wan8302TCP 、UDPagent server使用此端口处理WAN中的与其他server的gossip(用于多个数据中心)
grpc8400TCPagent用于处理从CLI来的RPC请求
http8500TCPagent用于处理HTTP API
dns8600TCP 、UDPagent用于处理 DNS 查询

2. consul的架构

2.1 Consul节点模式

Consul分为Client和Server两种节点(所有的节点也被称为Agent)。

Consul节点模式:

  • CLIENT : CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。
  • SERVER: SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。
  • SERVER-LEADER: 表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。

2.2 架构

在这里插入图片描述

  • 首先Consul支持多数据中心,在上图中有两个DataCenter,他们通过Internet互联,同时请注意为了提高通信效率,只有Server节点才加入跨数据中心的通信。
  • 在单个数据中心中,Consul分为Client和Server两种节点(所有的节点也被称为Agent),Server节点保存数据,Client负责健康检查及转发数据请求到Server;Server节点有一个Leader和多个Follower,Leader节点会将数据同步到Follower。虽然Consul可以运行在一台server , 但是建议使用3到5台来避免失败情况下数据的丢失.每个数据中心建议配置一个server集群。
  • 集群内的Consul节点通过gossip协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在还有哪些节点,这些节点是Client还是Server。单个数据中心的流言协议同时使用TCP和UDP通信,并且都使用8301端口。跨数据中心的流言协议也同时使用TCP和UDP通信,端口使用8302。
  • 集群内数据的读写请求既可以直接发到Server,也可以通过Client使用RPC转发到Server,请求最终会到达Leader节点,在允许数据轻微陈旧的情况下,读请求也可以在普通的Server节点完成,集群内数据的读写和复制都是通过TCP的8300端口完成。

3. 集群搭建

准备三台虚拟机,每台虚拟机搭建一个server和一个client,共计三个server和三个client。

3.1 环境准备

节点IP操作系统角色
consul-1192.168.66.131centos7consul-server, consul-client
consul-2192.168.66.132centos7consul-server, consul-client
consul-3192.168.66.133centos7consul-server, consul-client

3.2 软件准备

  • linux - centos7系统
  • Xshell
  • Xftp
  • consul_1.11.4_linux_amd64.zip

3.3 搭建过程

3.3.1 关闭防火墙

关闭: systemctl stop firewalld
开机禁用 : systemctl disable firewalld

3.3.2 下载软件

cd /soft

wget https://releases.hashicorp.com/consul/1.11.4/consul_1.11.4_linux_amd64.zip

mkdir -p  /usr/local/consul/bin

unzip consul_1.11.4_linux_amd64.zip -d /usr/local/consul/bin

配置环境变量:
vi /etc/profile, PATH=$PATH:/usr/local/consul/bin

source /etc/profile

在这里插入图片描述

consul --version

在这里插入图片描述
注意:也可以自行到官网下载软件,然后上传到linux。

3.3.3 配置client端口

由于server和client同时部署在一台虚拟机,为避免端口冲突,这里需改client的接口(修改server端口也可以)。

mkdir -p /usr/local/consul/config

cd /usr/local/consul/config

touch ports.json

vi ports.json

添加如下配置:

{
    "ports":{
        "http":8501,
        "dns":8601,
        "serf_lan":8311,
        "serf_wan":8312,
        "server":8310
    }
}

在这里插入图片描述

3.3.4 编写shell脚本

  • 启动client脚本-client.sh
#!/bin/sh


leader="192.168.66.131"
ip_addr=`ifconfig | grep -A 1 ens33 | grep "inet" | awk '{print $2}'`
client_out_file=client_consul_`date +"%Y%m%d%H%M%S"`.log

data_dir=/usr/local/consul/data
logs_dir=/usr/local/consul/logs
config_dir=/usr/local/consul/config

if [ ! -d $data_dir ]; then
	mkdir $data_dir
fi
if [ ! -d $logs_dir ]; then
	mkdir $logs_dir
fi

nohup /usr/local/consul/bin/consul agent -datacenter=DC01 -bind=$ip_addr -client=$ip_addr -data-dir=$data_dir -ui -node=$ip_addr:client -config-dir=$config_dir -retry-join $leader -node-id=$(uuidgen | awk '{print tolower($0)}') > $logs_dir/$client_out_file 2>&1 &

注意:-node-id=$(uuidgen | awk ‘{print tolower($0)}’), 加这个是因为server和client同时部署在一台虚拟机,id重复,报错。

  • 启动server脚本-server.sh
#!/bin/sh

leader="192.168.66.131"
ip_addr=`ifconfig | grep -A 1 ens33 | grep "inet" | awk '{print $2}'`
server_out_file=server_consul_`date +"%Y%m%d%H%M%S"`.log

data_dir=/usr/local/consul/data
logs_dir=/usr/local/consul/logs

if [ ! -d $data_dir ]; then
	mkdir $data_dir
fi
if [ ! -d $logs_dir ]; then
	mkdir $logs_dir
fi



if [ $leader = $ip_addr ]; then
   nohup /usr/local/consul/bin/consul agent -datacenter=DC01 -server -bootstrap-expect=2 -bind=$ip_addr -client=$ip_addr -data-dir=$data_dir -ui -node=$ip_addr:server > $logs_dir/$server_out_file 2>&1 &
else
   nohup /usr/local/consul/bin/consul agent -datacenter=DC01 -server -bootstrap-expect=2 -bind=$ip_addr -client=$ip_addr -data-dir=$data_dir -ui -node=$ip_addr:server -retry-join $leader > $logs_dir/$server_out_file 2>&1 &
fi
  • 启动client和server脚本-startUp.sh
#!/bin/sh

sh /usr/local/consul/server.sh
sh /usr/local/consul/client.sh

在这里插入图片描述

  • 配置解释
#配置说明:
-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上生效
-pid-file:提供一个路径来存放pid文件,可以使用该文件进行SIGINT/SIGHUP(关闭/更新)agent

更详细配置看官方:Agent/Configuration

3.4 访问

启动脚本:

./startup.sh

http://192.168.66.131:8501/ui/dc01/nodes
在这里插入图片描述

参考资料

  1. https://juejin.cn/post/6844904132214538248
  2. https://blog.csdn.net/qq_38659629/article/details/82804449
  3. https://www.imooc.com/article/284070
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐