consul实践--运行原理

在上一节中,展示了如何安装consul,本文,我们将继续深入的探究consul。

本文将:

  1. 给出一个简单的启动示例
  2. 简介consul的架构
  3. 搭建3个server和3个client的集群

简单示例

我们将常用命令放到本文中来对照:

consul agent        ##代理

-bind=0.0.0.0       ## 指定consul所在机器的IP地址,默认是0.0.0.0
-http-port=8500     ## consul自带一个web访问的默认端口
-client=127.0.0.1   ## 表明哪些机器可以访问consul,默认本机,0.0.0.0表示所有机器均可访问
-config-dir=foo     ## 所有主动注册服务的描述信息
-data-dir=path      ## 储存所有注册过来的server机器的详细信息
-dev                ## 开发者模式,直接以默认的配置启动consul
-node=hostname      ## 服务发现的名字(节点名称)
-rejion             ## consul启动的时候,加入到consul的集群
-server             ## 以服务方式开启consul,运行其他的consul连接到开启的consul上(形成了集群)。如果不加-server,表示以“客户端”的方式开启,不能被连                        接。
-ui                 ## 可以使用web页面来查看服务发现的详情

比如,启动一个consul server,可以使用如下命令:

consul agent -server -bootstrap-expect=1 -data-dir=/tmp/consul -node=consulServer_1 -ui -config-dir=/etc/consul.d/ -client 0.0.0.0

说明:

  • -server,以服务方式开启consul;不加这个的话,就是以客户端的形式启动,不具备服务端的一些特性,如持久化保存节点数据等
  • bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。
  • -data-dir,将所有注册过来的server机器的详细信息存储在/tmp/consul目录
  • 服务发现的名称命名为consulServer_1
  • -ui ,可以使用web页面来查看服务发现的详情
  • -config-dir,在/etc/consul.d/文件夹下,以json 文件形式写服务配置,主动注册服务
  • -client,所有机器都可用访问这个consul

启动完成后,即可连接consul,使用服务发现等功能。

接下来,我们先讲解一下Consul的基本架构,便于我们的使用。

Consul 架构

如下图所示,是Consul 的架构:

在这里插入图片描述

在每个数据中心内,consul 混合了客户端(client)和服务器(server)。

其中,预计将有三到五台服务器。 这会在故障情况下的可用性与性能之间取得平衡,因为随着添加更多计算机,共识会逐渐变慢。 但是,客户端的数量没有限制,他们可以轻松扩展到成千上万。

每个数据中心中的服务器都是单个Raft对等集的一部分。 这意味着他们将共同选举一个领导者,一个具有额外职责的选定服务器。 负责人负责处理所有查询和交易。 作为共识协议的一部分,还必须将事务复制到所有对等方。 由于此要求,当非领导服务器(follower)收到RPC请求时,它将转发给集群领导。

几个概念

  • Agent:是在 Consul 集群的每个成员上长期运行的守护进程,通过命令 consul agent 启动运行。由于所有节点都必须运行一个 Agent,因此 Agent 可以分为 client 或 Server。

  • Client:是将所有RPC转发到 Server 的 Agent。Client 是相对无状态的,Client 唯一执行的后台活动是加入 LAN gossip 池。这只有最小的资源开销,且只消耗少量的网络带宽

  • Server:是一个有一组扩展功能的 Agent,这些功能包括参与 Raft 选举、维护集群状态、响应RPC查询、与其他数据中心交互 WAN gossip 和转发查询给 leader 或远程的数据中心

  • Consensus:一致性。Consul 使用 Consensus 协议(具体由 Raft 算法实现)来提供一致性(由 CAP 定义),表明 leader 选举和事务的顺序达成一致

  • Gossip:Consul: 使用 Gossip 协议来管理成员资格并向集群广播消息。Serf 提供了完整的 Gossip 协议,可用于多种目的,而 Consul 建立在 Serf 之上。

  • LAN Gossip:指包含所有位于同一局域网或数据中心的节点的 LAN gossip 池

  • WAN Gossip:指仅包含 Server 的 WAN gossip 池。这些 Server 主要分布在不同的数据中心,通常通过Internet或者广域网进行通信

  • RPC:远程过程调用。一种 请求/响应 机制,允许 Client 向 Server 发起请求

更多概念,可以参考官网文档:https://www.consul.io/docs

几个问题

这里有两个问题,解答一下:

  • 不使用client客户端行不行?即,只使用Consul的Server模式

    答:可以。上面的简单示例就是可以运行的,也就是说,只有Server端,当需要用到服务发现时,直接连接Server端即可。

  • 接着问,既然可以,那为什么还需要Client端呢?

    答:因为Consul Server数量不是越多越好,需要考虑压力承载(扩展性)问题。此外,Server很少有一个Server下会注册很多微服务,当Server挂掉,这个Server节点下注册的微服务都会视为无效。

基于上述问题,我们在架构中加入Consul Client模式,Client因为加入了LAN gossip协议组成网络中(高速局域网),可以识别故障的Server节点并找到可用的Server节点继续工作。

其实Server模式负责的是用WAN gossip协议组成的网络进行跨广域网的数据同步(多个数据中心),这点Client模式是做不到的,Client模式也提供服务的注册和查询,但Client模式不存储节点数据,Client将请求转发给Server进行处理,节点注册数据在Server端是持久化保存的。

注意,一般情况下,Server的数量是受控制的,而Client的数量可以无限多。

总之:Client模式+LAN gossip协议组成了一个数据中心中的各个节点,Server负责投票选出Leader进行数据中心内的数据同步,这个Leader还负责利用WAN gossip协议跨广域网的与其他数据中心进行数据同步。

PS:在Client注册的服务心跳监控检查由Client负责。

如何进行服务发现

如下图所示,展示了服务D是如何通过consul发现服务B的:
在这里插入图片描述

实验

docker拉取镜像:

root@cchui-virtual-machine:~# docker pull consul
Using default tag: latest
latest: Pulling from library/consul
339de151aab4: Pull complete 
479a746f994b: Pull complete 
73e6c1395cf2: Pull complete 
5ceaa195774c: Pull complete 
67ff69bc8fb8: Pull complete 
4c9b2ffb3112: Pull complete 
Digest: sha256:0dc30c8081ea3cb4a90c908a571cb4aa469ae9e3d2b27d9fb713031127360e42
Status: Downloaded newer image for consul:latest
docker.io/library/consul:latest

启动3个Server 和 3个 Client

之后,这 6 个docker服务组建一个集群。

启动server

启动节点A

docker run -it -p 8500:8500 --name=ConsulServer-1 consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0

说明:

  • -it: 交互形式

  • -p 8500:8500:映射8500的端口

  • --name=ConsulServer-1:docker名称

  • consul为需要启动的镜像,后面的,属于consul的启动命令:

    consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0
    
    # -server: 作为服务端启动
    # -ui:可以使用web页面来查看服务发现的详情
    # -node=Server-A: 节点名称为Server-A
    # -bootstrap-expect=3:集群要求的最少server数量为3
    # -client=0.0.0.0:所有机器均可访问
    

启动成功后,出现:

oot@cchui-virtual-machine:~# docker run -it -p 8500:8500 --name=ConsulServer-1 consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0
==> Starting Consul agent...
           Version: '1.9.5'
           Node ID: 'e638fc87-fbfd-5ea2-d37a-100e1dfd2748'
         Node name: 'Server-A'
        Datacenter: 'dc1' (Segment: '<all>')
            Server: true (Bootstrap: false)
       Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: -1, gRPC: -1, DNS: 8600)
      Cluster Addr: 172.17.0.2 (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false

==> Log data will now stream in as it occurs:
    ......

可用得知,其docker内的IP地址为 172.17.0.2

此外,还可以使用:

## 或者使用 docker inspect ConsulServer-1
root@cchui-virtual-machine:~# docker inspect 3f84110d97ab
[
    {
        "Id": "3f84110d97ab1b8569dfc90c700f37052ea27ba0514259251d92f36a693ffa8e",
        "Created": "2021-04-29T07:25:15.831391139Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "agent",
            "-server",
            "-ui",
            "-node=Server-A",
            "-bootstrap-expect=3",
            "-client=0.0.0.0"
        ],
        ......
        "NetworkSettings": {
            ......
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "63a7356e019829b92981ba76fff8e0323e65bb97c5045d03f1a7900d47d6d35b",
                    "EndpointID": "7daf65d294211b6ecd69df208bacc58530bb4b5f4374d98916320590e24115c1",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

之后,再启动其他两个docker:

启动另外两个server节点

# 启动节点B
docker run -d -p 8501:8500 --name=ConsulServer-2 consul agent -server -ui -node=Server-B -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2
# 启动节点C
docker run -d -p 8502:8500 --name=ConsulServer-3 consul agent -server -ui -node=Server-C -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2

说明:

  • -d,以后台运行的方式,在后台运行

查看节点A日志

可以看到,之前,一直是有日志错误:

2021-04-29T07:33:21.542Z [ERROR] agent: Coordinate update error: error="No cluster leader"
2021-04-29T07:33:24.034Z [ERROR] agent.anti_entropy: failed to sync remote state: error="No cluster leader"

表示当前没有Raftleader

但是,当三个节点连接成网后,一段时间后,就开始选举领导者,同步数据了:

root@cchui-virtual-machine:~# docker run -it -p 8500:8500 --name=ConsulServer-1 consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0
==> Starting Consul agent...
......
==> Log data will now stream in as it occurs:
......
==> Consul agent running!
    2021-04-29T07:52:38.401Z [ERROR] agent.anti_entropy: failed to sync remote state: error="No cluster leader"
    2021-04-29T07:52:38.742Z [WARN]  agent.server.raft: no known peers, aborting election
    # 节点 Server-B 加入集群
    2021-04-29T07:52:59.231Z [INFO]  agent.server.serf.lan: serf: EventMemberJoin: Server-B 172.17.0.3
    ......
    # 节点 Server-C 加入集群
    2021-04-29T07:53:06.841Z [INFO]  agent.server.serf.lan: serf: EventMemberJoin: Server-C 172.17.0.4
    ......
    # 开始进行 Raft 选举 leader
    2021-04-29T07:53:10.416Z [WARN]  agent.server.raft: heartbeat timeout reached, starting election: last-leader=
    # Server-A 成为候选者 Candidate
    2021-04-29T07:53:10.416Z [INFO]  agent.server.raft: entering candidate state: node="Node at 172.17.0.2:8300 [Candidate]" term=2
    2021-04-29T07:53:10.428Z [INFO]  agent.server.raft: election won: tally=2
    # Server-A 成为领导者 Leader
    2021-04-29T07:53:10.428Z [INFO]  agent.server.raft: entering leader state: leader="Node at 172.17.0.2:8300 [Leader]"
    ......
    2021-04-29T07:53:10.429Z [INFO]  agent.server: New leader elected: payload=Server-A
    ......
    # 开始同步数据
    2021-04-29T07:53:10.533Z [INFO]  agent: Synced node info

最终,选举节点A作为领导者:

通过查看web网页,也可以看到leader:

http://IP:8501/ui/dc1/nodes

在这里插入图片描述

启动Client

启动第一个客户端:

docker run -it -p 9001:9001 --name=ConsulClient-1 consul agent -node=Client-1 -client=0.0.0.0 -join 172.17.0.2

在这里插入图片描述

此Docker运行的是Consul Client模式,并加入了Consul Server A(加入那个Consul Server都可以)。

# 启动第二个客户端
docker run -d -p 9002:9001 --name=ConsulClient-2 consul agent -node=Client-2 -client=0.0.0.0 -join 172.17.0.3
# 启动第三个客户端
docker run -d -p 9003:9001 --name=ConsulClient-3 consul agent -node=Client-3 -client=0.0.0.0 -join 172.17.0.4

查看界面:

在这里插入图片描述

停止

docker stop $(docker ps -aq)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值