Consul 随记

consul 包含多个组件,但是作为一个整体对外提供服务发现和服务配置工具:

提供的关键特性有:

服务发现:发现的是服务对应的IP地址和PORT端口号

健康检查:检查服务节点状态

Key/Value存储 :提供动态配置(简易配置文件或者键值对数据库)

多数据中心:开箱支持分布式

 

Consul  Agent  Server( 每个数据中心建议3-5台Server集群 )

基础设施中需要发现其他服务的组件:可以查询 Consul agent 或者 server

Consul集群的每个节点都必须先安装Consul :

例如:192.168.10.10    192.168.10.11  192.168.10.12  192.168.10.13   192.168.10.14  五台主机组合成一个 Consul集群,则 每个IP地址对应的服务器节点 都必须安装 Consul. 这五台主机中至少有一台agent 运行 server 模式,其他agent运行 client 模式

 

运行Agent (必须在集群的每一个主机上运行Agent):运行模式有两种server 和 client

consul members: 命令可以查看Consul 集群成员(节点)

localhost:8500/v1/catalog/nodes  =>   HTTP API(将自动转发)到Consul Server 查询集群成员 [ DNS也可以用来查询节点 ]

当一个成员离开时,他的服务与检测也会从目录中移除,成员失效,他的健康状态标记为危险,但不会被移除列表,后期会尝试重连接恢复,离开的节点不会再联系

 

注册一个服务并查询服务:

可以通过提供服务定义或者调用HTTP API来注册一个服务.服务定义文件是注册服务的最通用的方式.

创建服务配置文件目录及文件

echo '{"service": {"name": "web", "tags": ["rails"], "port": 80}}' \
    >/etc/consul.d/web.json

$ consul agent -dev -config-dir /etc/consul.d
==> Starting Consul agent...
...
    [INFO] agent: Synced service 'web'
...
重启Consul 即可载入服务定义并 成功注册到服务目录
多个服务只需要:创建多个服务定义文件

  

查询服务:

可以通过DNS或者HTTP的API来查询服务

在DNS API中,服务的DNS名字是 NAME.service.consul

NAME 是我们的服务名称:上例为 web

dig @127.0.0.1 -p 8600 web.service.consul

dig @127.0.0.1 -p 8600 web.service.consul SRV

会返回 web 这个服务运行的节点 hdp2.node.dc1.consul 和端口号,以及节点的A记录

TAGS.NAME.service.consul 可以通过DNS TAG来过滤服务
dig @127.0.0.1 -p 8600 rails.web.service.consul SRV

  

查询所有服务:
http://localhost:8500/v1/catalog/services

查询 web服务
http://localhost:8500/v1/catalog/service/web

条件查询web服务
http://localhost:8500/v1/catalog/service/web?passing

以上服务均可以用配置文件的方式或者HTTP API 做服务更新(可保持服务不关闭)

  

建立服务集群:

当一个节点agent启动时,他是一个成员的孤立集群.为了了解其他集群成员这个agent必须加入一个已经存在的集群.要加入一个已经存在的集群,只需要知道一个已经存在的集群成员.通过与这个成员的沟通来发现其他成员,Consul agent可以加入任何agent而不只是处于server模式的agent。

启动另外的4台服务器节点:192.168.10.11  192.168.10.12  192.168.10.13   192.168.10.14  安装agent并启动

我们可以使用 cnsul agent -dev 参数来快速启动一个开发模式的server 但是这并不能在集群环境中使用,我们用 集群环境配置来替换 -dev参数。

每个集群中的节点(如服务器:192.168.10.11)都必须要一个唯一的名字.Consul默认会使用机器的hostname.我们可以使用-node手动覆盖

使用-bind指定一个绑定的地址让Consul在这个地址上进行监听,这个地址必须可以被其他集群成员访问到.绑定地址不是必须提供

-server 参数 将使节点 扮演集群的唯一server

config-dir /etc/consul.d 选项,指定服务和健康检查定义文件存放的路径

 

至此:有了两个运行了Consul 的Agent, 一个是server,一个是client 

这两个agent还互相不知道对方,只是作为独立的单节点集群.为了验证这个你可以在每个agent运行consul member,只能看到各自自己这一个集群成员.

 

加入集群:

consul join 192。168.10.10  // 两个agent 下 运行 consul members 均可以看到来个成员节点。

  

自动加入集群设置:-atlas-join选项

DNS API中节点名称结构为 NAME.node.consul或者NAME.node.DATACENTER.consul.如果数据中心名字省略,Consul只会查询本地数据中心.

dig @127.0.0.1 -p 8600 hdp3.node.consul

  

 
服务注册:
http://127.0.0.1:8500/v1/catalog/register
{
  "Datacenter": "dc1", // 数据中心
  "ID": "40e4a748-2192-161a-0510-9bf59fe950b5", // 服务唯一ID
  "Node": "foobar", // 节点名称
  "Address": "192.168.10.10", // 节点IP
  "TaggedAddresses": { // 网络地址
    "lan": "192.168.10.10",
    "wan": "10.0.10.10"
  },
  "NodeMeta": { // 节点标记
    "somekey": "somevalue"
  },
  "Service": {
    "ID": "redis1", // 服务唯一ID
    "Service": "redis", // 服务名称
    "Tags": [ // 服务名相同时,服务标签
      "primary",
      "v1"
    ],
    "Address": "127.0.0.1", // 服务发现地址
    "Meta": {
        "redis_version": "4.0" // 版本
    },
    "Port": 8000 // 服务发现端口
  },
  "Check": { // 健康检查
    "Node": "foobar", // 待检查的节点
    "CheckID": "service:redis1", // 待检查的服务ID
    "Name": "Redis health check", // 检查名称
    "Notes": "Script based health check", // 检查标记
    "Status": "passing", // 健康检查状态
    "ServiceID": "redis1", // 待检查服务ID
    "Definition": {  // 检查详细度
      "TCP": "localhost:8888",
      "Interval": "5s",
      "Timeout": "1s",
      "DeregisterCriticalServiceAfter": "30s" // 如果健康检查不通过 30s 后服务下线
    }
  },
  "SkipNodeUpdate": false // 忽略节点更新?
}


查询服务详细信息:
http://127.0.0.1:8500/v1/catalog/service/${serviceName}
示例:
http://127.0.0.1:8500/v1/catalog/service/Golang


查询所有的服务:
http://127.0.0.1:8500/v1/catalog/services
示例:
http://127.0.0.1:8500/v1/catalog/services

查询节点名称详细信息:
http://127.0.0.1:8500/v1/catalog/node/${nodeName} 

示例:
http://127.0.0.1:8500/v1/catalog/node/Golang

  同一Node节点可以注册多个服务

健康检查:

添加健康检查到节点和服务.健康检查是服务发现的关键组件.预防使用到不健康的服务

和服务类似,一个检查可以通过检查定义或HTTP API请求来注册

echo '{"check": {"name": "ping",
  "script": "ping -c1 163.com >/dev/null", "interval": "30s"}}' \
  >/etc/consul.d/ping.json

通过HTTP形式来查询节点健康状态
http://localhost:8500/v1/health/state/critical

我们可以尝试用DNS查询web服务,Consul将不会返回结果.因为服务不健康
dig @127.0.0.1 -p 8600 web.service.consul
 

键值数据存储:

Consul 提供的易用键值存储功能:用来保持动态配置,协助服务协调,领袖选举,做开发者可以想到的任何事情

 

//  检查 是否存储有key  ?recurse参数可以获取多个key值
curl -v http://localhost:8500/v1/kv/?recurse

// put key值
curl -X PUT -d 'test' http://localhost:8500/v1/kv/web/key1
curl -X PUT -d 'test' http://localhost:8500/v1/kv/web/key2?flags=42

// 获取单个key值
curl http://localhost:8500/v1/kv/web/key1

// 删除用delete方法

设置自托管的UI服务

consul agent -ui

  

查询leader领导者:
返回的是领导者节点IP

http://172.17.0.4:8500/v1/status/leader

  

端口:

8300:consul agent服务relplaction、rpc(client-server)

8301:lan gossip

8302:wan gossip

8500:http api端口

8600:DNS服务端口

 

注册中心:每个服务提供者向注册中心登记自己提供的服务,将服务名与主机IP、端口等一些附加信息告知服务中心,注册中心按服务名分类组织服务清单。如A服务运行在192.168.1.82:3000,192.168.1.83:3000实例上。那么维护的内容如下:

服务 实例
A服务 192.168.99.10:3000    192.168.99.11:300

 

同时注册中心也会还会以心跳的方式去检查服务是否可用,如果不可用,则从服务实例中剔除。

服务消费者:在微服务的治理框架,服务之间的调用不再通过具体实例地址访问,而是向服务名发起调用实现。如上述例子,在注册中心注册A服务后,访问A服务的的调用方法就变为http://A服务/xxxx(代码层面是通过服务名调用服务,而不是域名!->解决了我很大的一个疑惑),通过以下的步骤,在真正发起请求时,把A服务替换为服务实例地址。

1. 服务消费者从服务消费者从订阅注册中心获取A服务所有实例地址;

2. 根据获取的实例地址通过负载均衡(后续有时间会写文章详细说明)的策略获取合适的Ip地址与端口,假设获取到的实例地址为:192.168.1.82:3000;

3. 把A服务地址替换为192.168.1.82:3000。

核心功能已介绍完成,下面我们就开始构建我们的注册中心。

 

consul相关概念

Agent

  1. Agent 是一个守护进程
  2. 运行在Consul集群的每个成员上
  3. 有Client 和 Server 两种模式
  4. 所有Agent都可以被调用DNS或者HTTP API,并负责检查和维护同步

Client

  1. Client 将所有RPC请求转发至Server
  2. Client 是相对无状态的
  3. Client 唯一做的就是参与LAN Gossip Pool
  4. Client 只消耗少量的资源和少量的网络带宽

Server

  1. 参与 Raft quorum(一致性判断)
  2. 响应RPC查询请求
  3. 维护集群的状态
  4. 转发查询到Leader 或 远程数据中心

 

Datacenter数据中心

  1. 私有的
  2. 低延迟
  3. 高带宽

 Gossip

一种协议: 用来保证 最终一致性 ,: 无法保证在某个时刻, 所有节点状态一致, 但可以保证”最终”一致

 

 

RPC(即Remote Procedure Call,远程过程调用

posted @ 2019-06-28 09:32  winyh  阅读(518)  评论(0编辑  收藏  举报