zoukankan      html  css  js  c++  java
  • consul分布式集群搭建

    环境准备

    三台机器:

    vm-a    10.200.110.90    centos7
    vm-b    10.200.110.91    centos7
    vm-c    10.200.110.93    centos7
    Consul官网(https://www.consul.io/downloads.html)下载相应系统的consul可执行文件并放系统PATH环境变量目录内。

    我下载的是consul_1.4.3_linux_amd64.zip,在上面的每台机器上解压,并拷贝到/usr/local/bin目录下。

    unzip consul_1.4.3_linux_amd64.zip
    mv cosul /usr/local/bin

     集群启动

    10.200.110.90启动consul
    consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=10.200.110.90 -bind=10.200.110.90 -client=0.0.0.0 -datacenter=shenzhen -ui
    10.200.110.91启动consul
    consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node 10.200.110.91 -bind=10.200.110.91 -client=0.0.0.0 -datacenter shenzhen -ui
    10.200.110.93启动consul
    consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node 10.200.110.93 -bind=10.200.110.93 -client=0.0.0.0 -datacenter shenzhen -ui

    参数说明:

    •  server: 以server身份启动。默认是client
    •  bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。
    •  data-dir:data存放的目录,更多信息请参阅consul数据同步机制
    •  node:节点id,集群中的每个node必须有一个唯一的名称。默认情况下,Consul使用机器的hostname
    •  bind:监听的ip地址。默认绑定0.0.0.0,可以不指定。表示Consul监听的地址,而且它必须能够被集群中的其他节点访问。Consul默认会监听第一个private IP,但最好还是提供一个。生产设备上的服务器通常有好几个网卡,所以指定一个不会出错
    •  client: 客户端的ip地址,0.0.0.0是指谁都可以访问(不加这个,下面的ui :8500无法访问)
    •  ui: 可以访问UI界面
    • -config-dir指定配置文件夹,Consul会加载其中的所有文件
    • -datacenter 指定数据中心名称,默认是dc1

    此时三台机器都会打印:

        2019/03/20 10:57:36 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp)
        2019/03/20 10:57:36 [INFO] agent: started state syncer
        2019/03/20 10:57:44 [ERR] agent: failed to sync remote state: No cluster leader

    此时三台机器还未join,不能算是一个集群,三台机器上的consul均不能正常工作,因为leader未选出。


    三台机器组成consul集群

    consul集群:当一个consul agent启动后,它不知道任何其他节点,要学习到集群中的其他节点,agent必须加入一个已经存在的集群(cluster)。要加入这样的集群,它只需要知道这个集群中的一个节点即可。它加入后,将会和这个member gossip(交谈)并迅速发现集群中的其他节点。一个consul agent可以加入任何类型的其他agent,而不只是那些运行于server mode的agent。

    分别登录第2台和第3台虚拟机上执行如下命令,让consul加入集群:
    10.200.110.91加入10.200.110.90

    [root@localhost consul-cluster]# consul join 10.200.110.90
    Successfully joined cluster by contacting 1 nodes.
    [root@localhost consul-cluster]#

    10.200.110.93加入10.200.110.90

    [root@localhost consul-cluster]# consul join 10.200.110.90
    Successfully joined cluster by contacting 1 nodes.
    [root@localhost consul-cluster]#

    很快三台机器都会打印:

        2019/03/20 10:59:12 [INFO] raft: Added peer d89335fd-cfb8-1fc0-3902-b847e125fa2c, starting replication
        2019/03/20 10:59:12 [INFO] consul: cluster leadership acquired
        2019/03/20 10:59:12 [INFO] consul: New leader elected: 10.200.110.90

    证明此时leader已经选出,集群可以正常工作。访问:http://10.200.110.90:8500/

    上图中的下拉框是datacenter的选项。


    集群状态查看

    [root@localhost ~]# consul operator raft list-peers
    Node           ID                                    Address             State     Voter  RaftProtocol
    10.200.110.90  239bfd6a-28d0-094a-4d93-09bf81414528  10.200.110.90:8300  leader    true   3
    10.200.110.91  d1b05900-4f8f-b956-5ba6-5a3c798d93d3  10.200.110.91:8300  follower  true   3
    10.200.110.93  d89335fd-cfb8-1fc0-3902-b847e125fa2c  10.200.110.93:8300  follower  true   3
    [root@localhost ~]# 

    查看members状态:

    [root@localhost ~]# consul members
    Node           Address             Status  Type    Build  Protocol  DC        Segment
    10.200.110.90  10.200.110.90:8301  alive   server  1.4.3  2         shenzhen  <all>
    10.200.110.91  10.200.110.91:8301  alive   server  1.4.3  2         shenzhen  <all>
    10.200.110.93  10.200.110.93:8301  alive   server  1.4.3  2         shenzhen  <all>
    [root@localhost ~]# 

    集群参数get/set测试

    10.200.110.93的set操作:

    [root@localhost ~]# consul kv put addr nanshan
    Success! Data written to: addr
    [root@localhost ~]#

    10.200.110.91的get操作:

    [root@localhost consul-cluster]# consul kv get addr
    nanshan
    [root@localhost consul-cluster]#

    在10.200.110.90可以正常设置key的值为value,并能正常查回来。三台机器获取key的值均为value,如此可知key的值已经在集群中同步。


    集群单机故障处理

    单机consul进程故障发生
    杀死三台机器中任意一台机器上的consul进程,这里杀死leader 192.168.1.235

    在10.200.110.90机器上执行:

    [root@localhost ~]# ps -ef | grep consul
    root      24811   7330  6 10:57 pts/0    00:12:44 consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=10.200.110.90 -bind=10.200.110.90 -datacenter=shenzhen -ui
    root      24957  24939  0 13:59 pts/1    00:00:00 grep --color=auto consul
    [root@localhost ~]# kill -9 24811
    [root@localhost ~]# 

    此时看此台机器上的consul的log:

        2019/03/20 11:03:36 [INFO] serf: EventMemberUpdate: 10.200.110.93.shenzhen
        2019/03/20 11:03:37 [WARN] raft: Failed to contact d89335fd-cfb8-1fc0-3902-b847e125fa2c in 2.500740308s
        2019/03/20 11:03:37 [INFO] raft: pipelining replication to peer {Voter d89335fd-cfb8-1fc0-3902-b847e125fa2c 10.200.110.93:8300}
    已杀死
    [root@localhost consul-cluster]# 

    Consul进程已经在这台机器上退出。
    此时都会10.200.110.91和10.200.110.93都会打印

    [ERR] agent: failed to sync remote state:No cluster leader

    [WARN] raft: Heartbeat timeout from"10.200.110.90:8300" reached, starting election

    Leader丢失,剩下的两台机重新进行leader选举

    [root@localhost ~]# consul operator raft list-peers
    Node           ID                                    Address             State     Voter  RaftProtocol
    10.200.110.93  d89335fd-cfb8-1fc0-3902-b847e125fa2c  10.200.110.93:8300  leader    true   3
    10.200.110.91  d1b05900-4f8f-b956-5ba6-5a3c798d93d3  10.200.110.91:8300  follower  true   3
    10.200.110.90  239bfd6a-28d0-094a-4d93-09bf81414528  10.200.110.90:8300  follower  true   3
    [root@localhost ~]#

    此时再对10.200.110.91和10.200.110.93进行key的get/set操作:

    [root@localhost ~]# consul kv get addr
    nanshan
    [root@localhost ~]# 

    均能正常get到key的值为nanshan。

    Consul 多数据中心配置 MULTIPLE DATACENTERS

    在consul集群中,多数据中心可以进行配置:
    LAN gossip pool包含了同一局域网内所有节点,包括server与client。这基本上是位于同一个数据中心DC。
    WAN gossip pool一般仅包含server,将跨越多个DC数据中心,通过互联网或广域网进行通信。
    我们之前讲过的启动集群命令使用的是-bootstrap 来作为服务的启动:

    10.200.110.95启动consul
    consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node 10.200.110.95 -bind=10.200.110.93 -datacenter guangzhou -ui

    查询当前集群下拥有的datacenter信息:
    consul members -wan

    我这里有两个数据中心shenzhen和guangzhou,使用下面的命令将数据中心互相可见:

    [root@localhost ~]# consul join -wan 10.200.110.91
    Successfully joined cluster by contacting 1 nodes.
    [root@localhost ~]#

    多数据中心就配好了,在之前的UI中也可以看到了:

    查询当前集群下拥有的datacenter信息:

    [root@localhost ~]# consul members -wan
    Node                     Address             Status  Type    Build  Protocol  DC         Segment
    10.200.110.91.shenzhen   10.200.110.91:8302  alive   server  1.4.3  2         shenzhen   <all>
    10.200.110.93.shenzhen   10.200.110.93:8302  alive   server  1.4.3  2         shenzhen   <all>
    10.200.110.95.guangzhou  10.200.110.95:8302  alive   server  1.4.3  2         guangzhou  <all>
    [root@localhost ~]#

     参照consul部署,部署两个数据中dc1和dc2。数据中心的名字对consul而言是不透明的,它们只是用于管理员与consul交互使用。

            通过consulmembers –wan命令可以查询WAN中的节点:

    $ consul members-wan
    ...
            输出结果是WAN gossip pool中的节点列表,只包含server节点。 client节点只会想本地数据中的server节点发送请求,不会加入WAN Gossip Pool。Client请求会通过本地数据中的Server节点转发到目标数据中心。

            下一步是保证所有的Server节点均加入到WAN gossip Pool。

    $ consul join -wan<server 1> <server 2> ...
    ...
            join命令加上-wan参数,是讲Server加入到WAN gossip pool。而LAN gossip pool,只需要加入到现有的某个Server节点即可,和通过gossip协议与其他成员交换信息即可知道所有的成员节点。然而,对于启动的consul的Server,只知道自己的信息,必须添加到群集中。

            一旦加入完成,基于WAN通过gossip协议就可以使用members命令查询所有的Server节点。

            我们也可以通过HTTP API来查询所有的数据中心:

    $ curlhttp://localhost:8500/v1/catalog/datacenters
    ["dc1", "dc2"]
            做一个简单的测试,查询某个数据中心的所有节点:

    $ curlhttp://localhost:8500/v1/catalog/nodes?dc=dc1
    ...
    $ curlhttp://localhost:8500/v1/catalog/nodes?dc=dc2
    ...
            构建多数据中心,网络需要满足如下要求:1.所有的Server节点都是互通,否则,基于gossip协议的RPC转发将无法工作。如果服务发现是可以跨数据中心,网络必须能够跨区域之间的路由的IP地址以及。2.如果使用服务发现,那么所有的数据中心都是互通的,或者基于VPN或其他隧道机制是互通的。Consul不能处理VPN、address rewritting,或者NAT traversal。

    SpringCloud在consul集群示例

    环境:

    ip 10.200.110.90 10.200.110.91 10.200.110.93 10.200.110.89 10.200.110.95
    consul agent consul agent server consul agent server consul agent server    
    app service-consumer     service-consumer  
    app         service-producter
    app          

    应用注册consul为:

    应用启动时注册到consul集群的命令行:

    java -jar -Dspring.cloud.consul.host=10.200.110.91 -Dserver.port=8091 -Dspring.cloud.consul.discovery.hostname=10.200.110.90 service-consumer-201903201556.jar

    现在测试consul集群的高可用性,将10.200.110.90的consul agent server停掉。

    service-consumer:

    service-producter:

    再触发一次service-consumer调用service-producter的测试,访问10.200.110.90:8091,调用到了10.200.110.95:8081的应用上。

    http://10.200.110.90:8091/swagger-ui.html#!/book-consumer/getbook5UsingGET

    consul的服务注册的两种方式:

    和《Consul之:服务注册与发现》有些重复。

    方式1:通过配置文件方式

    通过在consul的服务器的工作目录中增加consul的配置文件的方式进行服务注册,

    例如,我在consul的机器上的/home/consul-cluster/config增加如下配置文件:

    复制代码
    {
        "service":
        {
            "name": "service-front",
            "tags": ["jar"],
            "address": "10.200.110.97",
            "port": 8001,
            "checks": [
            {
                "http": "http://10.200.110.97:8001/health",
                "interval": "10s"
            }]
        }
    }
    复制代码

     如果有多个服务时,

    复制代码
    {
        "services": [{
            "id":"front1",
            "name": "service-front",
            "tags": ["local-dev"],
            "address": "10.200.110.100",
            "port": 8001,
            "checks": [{
                "http": "http://10.200.110.100:8001/health",
                "interval": "10s"
            }]
        },
         {
            "id":"front2",
            "name": "service-front",
            "tags": ["jar"],
            "address": "10.200.110.97",
            "port": 8001,
            "checks": [{
                "http": "http://10.200.110.97:8001/health",
                "interval": "10s"
            }]
        }]
    }
    复制代码

    在consul的控制台上,可见服务注册成功。如下:

    或者通过命令行查看验证服务是否注册成功:

    复制代码
    [root@localhost consul-template]# curl http://10.200.110.90:8500/v1/catalog/service/service-front
    [{"ID":"d1b05900-4f8f-b956-5ba6-5a3c798d93d3","Node":"10.200.110.91","Address":"10.200.110.91","Datacenter":"shenzhen","TaggedAddresses":{"lan":"10.200.110.91","wan":"10.200.110.91"},"NodeMeta":{"consul-network-segment":""},"ServiceKind":"","ServiceID":"service-front-10-200-110-100-8001","ServiceName":"service-front","ServiceTags":["front-dev,这是个前置应用,网关层","duan"],"ServiceAddress":"10.200.110.100","ServiceWeights":{"Passing":1,"Warning":1},"ServiceMeta":{},"ServicePort":8001,"ServiceEnableTagOverride":false,"ServiceProxyDestination":"","ServiceProxy":{},"ServiceConnect":{},"CreateIndex":11382,"ModifyIndex":11382},{"ID":"382f88c2-4482-e1f7-1453-28f94ff65108","Node":"10.200.110.97","Address":"10.200.110.97","Datacenter":"shenzhen","TaggedAddresses":{"lan":"10.200.110.97","wan":"10.200.110.97"},"NodeMeta":{"consul-network-segment":""},"ServiceKind":"","ServiceID":"front1","ServiceName":"service-front","ServiceTags":["local-dev"],"ServiceAddress":"","ServiceWeights":{"Passing":1,"Warning":1},"ServiceMeta":{},"ServicePort":8001,"ServiceEnableTagOverride":false,"ServiceProxyDestination":"","ServiceProxy":{},"ServiceConnect":{},"CreateIndex":11976,"ModifyIndex":11976}][root@localhost consul-template]#
    复制代码

    方式2:通过consul api方式

    复制代码
    spring.cloud.consul.discovery.enabled: true
    spring.cloud.consul.discovery.healthCheckInterval: 10s
    spring.cloud.consul.discovery.instanceId: ${spring.application.name}:${spring.cloud.consul.discovery.hostname}:${server.port}
    spring.cloud.consul.enabled: true
    spring.cloud.consul.host: 10.200.110.100
    spring.cloud.consul.port: 8500
    spring.zipkin.base-url: http://10.200.110.4:9411
    
    management.security.enabled: false 
    
    server:
      port: 8001
    spring:
      application:
        name: service-front
        author: duanxz
        description: service-front
      cloud:
        consul:
          discovery:
            hostname: 127.0.0.1
            tags:
            - front-dev,这是个前置应用,网关层
            - duan
    复制代码

    待解决的问题

    我组成的2个服务:

    复制代码
    [root@localhost config]# cat apps.json 
    
    {
        "services": [{
            "id":"front1",
            "name": "service-front",
            "tags": ["local-dev"],
            "port": 8001,
            "checks": [{
                "http": "http://10.200.110.97:8001/health",
                "interval": "10s"
            }]
        },
         {
            "id":"demo",
            "name": "service-demo",
            "tags": ["jar"],
            "address": "10.200.110.97",
            "port": 8071,
            "checks": [{
                "http": "http://10.200.110.97:8071/health",
                "interval": "10s"
            }]
        }]
    }
    [root@localhost config]#
    复制代码

    通过json配置文件的方式,注册到consul上的服务间无法通过Feign调用,

    我的demo里,是service-front调用service-demo,打开swagger调用出现如下错误:

    复制代码
    {
      "timestamp": 1553161721543,
      "status": 500,
      "error": "Internal Server Error",
      "exception": "java.lang.RuntimeException",
      "message": "Request processing failed; nested exception is java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-demo",
      "path": "/book/show6/1"
    }
    复制代码

    转自:学无止境:https://www.cnblogs.com/duanxz/p/10564502.html

  • 相关阅读:
    Python 基础之函数初识与函数参数
    python 基础之浅拷贝与深拷贝
    Python 基础之集合相关操作与函数和字典相关函数
    Python 基础之字符串操作,函数及格式化format
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
  • 原文地址:https://www.cnblogs.com/Leslieblog/p/12665790.html
Copyright © 2011-2022 走看看