Docker安装consul

Docker安装consul,第1张

consul注册发现 1 . 1 . consul简介?

​ consul是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与 发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其 他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要 运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以 保证数据安全,同时保证server-leader的选举能够正确的进行。

类似的工具还有:ZooKeeper,etcd等等。

1 . 2 . 为什么使用服务发现

​ 防止硬编码、容灾、水平扩缩容、提高运维效率等等,只要你想使用服务发现总能找到合适的理由。 一般的说法是因为使用微服务架构。传统的单体架构不够灵活不能很好的适应变化,从而向微服务架构 进行转换。 而伴随着大量服务的出现,管理运维十分不便,于是开始搞一些自动化的策略,服务发现应运而生。所 以如果需要使用服务发现,你应该有一些对服务治理的痛点。 但是引入服务发现就可能引入一些技术栈,增加系统总体的复杂度,如果你只有很少的几个服务,比如 10 个以下,并且业务不怎么变化,吞吐量预计也很稳定,可能就没有必要使用服务发现。

1 . 3 . consul工作原理

掌握原理前,需了解下consul的组成结构,即多数据中心

集群中的特性功能:

  • 节点角色:leader(领导者)、Follower(跟随者)
  • consul节点身份:server、client
  • Agent:即节点内包含的一个后台处理程序
  • 健康检查:由client的Agent来进行健康检查的功能

​ 首先 Consul 支持多数据中心,在上图中有两个 DataCenter,他们通过 Internet 互联,同时请注意为了 提高通信效率,只有 Server 节点才加入跨数据中心的通信。

在单个数据中心中,Consul 分为 Client 和 Server 两种节点(所有的节点也被称为 Agent),Server 节 点保存数据,Client 负责健康检查及转发数据请求到 Server。

​ Server 节点有一个 Leader 和多个 Follower,Leader 节点会将数据同步到 Follower,Server 的数量推 荐是 3 个或者 5 个,在 Leader 挂掉的时候会启动选举机制产生一个新的 Leader。

​ 集群内的 Consul 节点通过 gossip 协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在 还有哪些节点,这些节点是 Client 还是 Server。

​ 单个数据中心的流言协议同时使用 TCP 和 UDP 通信,并且都使用 8301 端口。跨数据中心的流言协议 也同时使用 TCP 和 UDP 通信,端口使用 8302。

​ 集群内数据的读写请求既可以直接发到 Server,也可以通过 Client 使用 RPC 转发到 Server,请求最终 会到达 Leader 节点。

​ 在允许数据轻微陈旧的情况下,读请求也可以在普通的 Server 节点完成,集群内数据的读写和复制都是 通过 TCP 的 8300 端口完成。

2 . consul服务发现原理

​ 首先需要有一个正常的 Consul 集群,有 Server,有 Leader。这里在服务器 Server1、Server2、 Server3 上分别部署了 Consul Server。

​ 假设他们选举了 Server2 上的 Consul Server 节点为 Leader。这些服务器上最好只部署 Consul 程序, 以尽量维护 Consul Server 的稳定。

​ 然后在服务器 Server4 和 Server5 上通过 Consul Client 分别注册 Service A、B、C,这里每个 Service 分别部署在了两个服务器上,这样可以避免 Service 的单点问题。

服务注册到 Consul 可以通过 HTTP API(8500 端口)的方式,也可以通过 Consul 配置文件的方式。

​ Consul Client 可以认为是无状态的,它将注册信息通过 RPC 转发到 Consul Server,服务信息保存在 Server 的各个节点中,并且通过 Raft 实现了强一致性。

​ 最后在服务器 Server6 中 Program D 需要访问 Service B,这时候 Program D 首先访问本机 Consul Client 提供的 HTTP API,本机 Client 会将请求转发到 Consul Server。

Consul Server 查询到 Service B 当前的信息返回,最终 Program D 拿到了 Service B 的所有部署的 IP 和端口,然后就可以选择 Service B 的其中一个部署并向其发起请求了。

​ 如果服务发现采用的是 DNS 方式,则 Program D 中直接使用 Service B 的服务发现域名,域名解析请 求首先到达本机 DNS 代理,然后转发到本机 Consul Client,本机 Client 会将请求转发到 Consul Server。

Consul Server 查询到 Service B 当前的信息返回,最终 Program D 拿到了 Service B 的某个部署的 IP 和端口。

3 . consul集群

4 . consul集群搭建
服务器ipconsul类型Node(节点名称)
192.168.48.128serverconsul_server_1
192.168.48.129serverconsul_server_2
192.168.48.132serverconsul_server_3
192.168.48.134clientconsul_client_4
1 . 执行命令拉取最新版本的 Consul 镜像:
docker pull consul:1.4.4
2 . 创建第一台consul_server_1,设置为leader
docker run -d -p 8500:8500 \
-v /docker/consul/data/server1:/docker/consul/data \
-v /docker/consul/conf/server1:/docker/consul/conf \
-h=node1 --net=host \
-e CONSUL_BIND_INTERFACE=ens33 \
--privileged=true \
--name consul_server_1 \
consul:1.4.4 agent \
-bind=192.168.48.128 \
-server=true -bootstrap-expect=3 -ui \
-node=consul_server_1 -client='0.0.0.0' \
-datacenter=xdp_dc \
-data-dir /docker/consul/data/ \
-config-dir /docker/consul/conf/
3 . 创建第二台consul_server_2,设置为跟随者
docker run -d -p 8500:8500 \
-v /docker/consul/data/server2:/docker/consul/data \
-v /docker/consul/conf/server2:/docker/consul/conf \
-h=node2 --net=host \
-e CONSUL_BIND_INTERFACE=ens33 \
--privileged=true \
--name consul_server_2 \
consul:1.4.4 agent \
-bind=192.168.48.129 \
-server=true -ui \
-node=consul_server_2 -client='0.0.0.0' \
-datacenter=xdp_dc \
-data-dir /docker/consul/data/ \
-config-dir /docker/consul/conf/ \
-join 192.168.48.128
4 . 创建第三台consul_server_3,设置为跟随者
docker run -d -p 8500:8500 \
-v /docker/consul/data/server3:/docker/consul/data \
-v /docker/consul/conf/server3:/docker/consul/conf \
-h=node3 --net=host \
-e CONSUL_BIND_INTERFACE=ens33 \
--privileged=true \
--name consul_server_3 \
consul:1.4.4 agent \
-bind=192.168.48.132 \
-server=true -ui \
-node=consul_server_3 -client='0.0.0.0' \
-datacenter=xdp_dc \
-data-dir /docker/consul/data/ \
-config-dir /docker/consul/conf/ \
-join 192.168.48.128
5 . 设置为客户端consul_client_4
docker run -d -p 8500:8500 \
-v /docker/consul/conf/client4:/docker/consul/conf \
-e CONSUL_BIND_INTERFACE=ens33 \
--name consul_client_4 -h=node4 --net=host \
--privileged=true consul:1.4.4 agent \
-node=consul_client_4 -config-dir=/docker/consul/conf \
-server=false -client=0.0.0.0 -datacenter=xdp_dc -join=192.168.48.128 -ui
6 . 查看投票状态
docker exec -it consul_name consul operator raft list-peers

7 . 查看集群成员
docker exec -it consul_name consul members

8 . 注意事项:关闭防火墙
systemctl status firewalld

systemctl stop firewalld
9 . 验证

http://192.168.48.128:8500/ui/xdp_dc/services/consul

​ 这些 Consul 节点在 Docker 的容器内是互通的,他们通过桥接的模式通信。但是如果主机要访问容器内 的网络,需要做端口映射。

​ 在启动容器时,将 Consul 的 8500 端口映射到了主机的 8500 端口,这样就可以方便的通过主机的浏览 器查看集群信息。

5 . Consul Client实例创建 1 . 创建services.json配置文件

向Consul注册user,product API服务 (使用的时候去掉注释)

{
    "services": [
        {
            //在192.168.48.129服务中创建一个user的tcp服务,端口为9501
            "id": "core.user-/192.168.48.129:9501",
            //consul服务名称
            "name": "core.user",
            //标签名称
            "tags": [ "xdp-/core.user" ],
            //绑定地址
            "address": "192.168.48.129",
            //绑定端口
            "port": 9501,
            //健康监测
            "checks": [
                {
                  //监测名称:自定义
                  "name": "core.user.check",
                  //监测地址,(这里区分tcp和http的类型)
                  //"http": "http://192.168.48.129:9501",
                  "tcp": "192.168.48.129:9501",
                  //心跳健康检测频率
                  "interval": "10s",
                  //检测超时时间
                  "timeout": "5s"
                }
            ]
        },
        {
            //在192.168.48.129服务中创建一个product的tcp服务,端口为9502
            "id": "core.product-/192.168.48.129:9502",
            "name": "core.product",
            "tags": [ "xdp-/core.product" ],
            "address": "192.168.48.129",
            "port": 9502,
            "checks": [
                {
                  "name": "core.product.check",
                  "tcp": "192.168.48.129:9502",
                  "interval": "10s",
                  "timeout": "5s"
                }
            ]
        }
    ]
}

2 . 创建TCP服务

在192.168.48.129服务中分别创建user,product的tcp服务,端口分别为9501,9502

user.conf , product.conf (配置相同的功能)

server {
   #监听端口
   listen 9501;
   proxy_connect_timeout 10s;
   #设置客户端和代理服务之间的超时时间,如果5分钟内没 *** 作将自动断开。
   proxy_timeout 300s;
   proxy_pass cloudsocket;
}

upstream cloudsocket {
   hash $remote_addr consistent;
   server 172.17.0.3:9501 weight=5 max_fails=3 fail_timeout=30s;
}

创建tcp服务

UserService.php , ProductService.php (配置相同的功能)


//创建Server对象,监听 127.0.0.1:9501 端口
$server = new Swoole\Server('0.0.0.0', 9502);

//监听连接进入事件
$server->on('Connect', function ($server, $fd) {
    echo "Hello: Product.\n";
});

//监听数据接收事件
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
    $server->send($fd, "Server: {$data}");
});

//监听连接关闭事件
$server->on('Close', function ($server, $fd) {
    echo "Client: Close.\n";
});

//启动服务器
$server->start();

3 . 启动consul服务

将 services.json 文件 分别放到四个 sonsul 服务器 本地映射 /docker/consul/conf/ 下的 server1,server2 ,server3 , client4的目录中,测试结果如下

4 . 测试请求

服务注册成功以后,调用方获取相应服务地址的过程就是服务发现。Consul 提供了多种方式。

HTTP API 方式

容器内:

curl http://127.0.0.1:8500/v1/health/service/core.user?passing=true

容器外:

http://192.168.48.128:8500/v1/health/service/core.user?passing=true

返回的信息包括注册的 Consul 节点信息、服务信息及服务的健康检查信息。

  • passing=true //过滤不健康节点
  • passing=false //不过滤

如果服务有多个部署,会返回服务的多条信息,调用方需要决定使用哪个部署,常见的可以随机或者轮 询。

​ 为了提高服务吞吐量,以及减轻 Consul 的压力,还可以缓存获取到的服务节点信息,不过要做好容错 的方案,因为缓存服务部署可能会变得不可用。具体是否缓存需要结合自己的访问量及容错规则来确 定。

​ 上边的参数 passing 默认为 false,也就是说不健康的节点也会返回,结合获取节点全部服务的方法,这 里可以做到获取全部服务的实时健康状态,并对不健康的服务进行报警处理。

6 . Consul的API *** 作: 6 . 1 . 本地请求:基于 Agent

请求例子:

http://192.168.48.134:8500/v1/agnect/services
/v1/agent/checks 				--获取本地agent注册的所有检查(包括配置文件和http注册)
/v1/agent/services 				--获取本地agent注册的所有服务
/v1/agent/members 				--获取集群中的成员
/v1/agent/self 					--获取本地agent的配置和成员信息
/v1/agent/join/<address> 		--触发本地agent加入node
/vq/agent/force-leave/<node> 	--强制删除node
/v1/agent/check/register 		--在本地agent增加一个检查项,使用PUT

方法传输一个json格式的数据
/v1/agent/check/deregister/<checkID> 	--注销一个本地agent的检查项
/v1/agent/check/pass/<checkID> 			--设置一个本地检查项的状态为passing
/v1/agent/check/warn/<checkID> 			--设置一个本地检查项的状态为warning
/v1/agent/check/fail<checkID> 			--设置一个本地检查项的状态为critical
/v1/agent/service/deregister/<serviceID> --注销一个本地agent的服务项
/v1/agent/service/register 		--在本地agent增加一个新的服务项,使用PUT方法传输一个json格式的数据
6 . 2 . 数据中心请求:基于 catalog 类型
/v1/catalog/register 			--注册一个新的service、node、check
/v1/catalog/deregister 			--注销一个service、node、check
/v1/catalog/datacenters 		--列出知道的数据中心
/v1/catalog/nodes 				--在给定的数据中心列出node
/v1/catalog/services 			--在给定的数据中心列出service
/v1/catalog/service/<service> 	--查看某个服务的信息
/v1/catalog/node/<node>
6 . 3 . 注册服务:(注意,需要请求consul_client的服务进行注册)

注:consul中注册服务与编辑服务的信息都是相同的接口

method: PUT

http://192.168.48.134:8500/v1/agent/service/register
{
	"id": "core.order-/192.168.48.129:9503",
	"name": "core.order",
	"tags": [ "xdp-/core.order" ],
	"address": "192.168.48.129",
	"port": 9503,
	"checks": [
		{
			"name": "core.order.check",
			//"http": "http://192.168.48.129:9503",
            "tcp": "192.168.48.129:9503",
			"interval": "10s",
			"timeout": "5s"
		}
	]
}

6 . 4 . 查询服务: 6 . 4 . 1 本地请求(Agent)

HTTP-API请求:查询本地节点下所有的注册服务

method: GET

http://192.168.48.134:8500/v1/agent/services

HTTP-API请求:查询指定本地节点下的服务

语法:/v1/agent/service/{serviceID}

method: GET

http://192.168.48.134:8500/v1/agent/service/core.user-/192.168.48.129:9501

单机性能压测如下

测试的机器性能比较差,也能如此并发,因此实际开发过程中,接口调用consul获取服务配置信息,不用担心性能与并发的问题,也无需做redis数据缓存(也可以缓存起来),只管调用即可。

6 . 4 . 2 数据中心(catalog)的查询方式:

/v1/catalog/services --在给定的数据中心列出service

/v1/catalog/service/ --查看某个服务的信息

HTTP-API:查询当前数据中心下的注册的服务

method:GET

http://192.168.48.134:8500/v1/catalog/services

HTTP-API:查询指定本地节点下的服务

语法:/v1/catalog/service/{name}

method:GET

http://192.168.48.134:8500/v1/catalog/service/core.user

6 .5 删除服务:

注销任意节点和服务:/v1/catalog/deregister

注销当前节点的服务:/v1/agent/service/deregister/{serviceID}

method: PUT

http://192.168.48.134:8500/v1/agent/service/deregister/core.order-/192.168.48.129:9503

​ 注意:如果注销的服务还在运行,则会再次同步到 catalog 中,因此应该只在 Agent 不可用时才使用 catalog 的注销 API。

节点在宕机时状态会变为 failed,默认情况下 72 小时后会被从集群移除。

停止代理:

如果某个节点不继续使用了,也可以在本机使用 consul leave 命令。

或者在其他节点使用 consul force-leave 故障节点 id,则节点上的服务和健康检查全部注销。

7 . Consul 集群之负载均衡

创建三台consul服务器,端口分别为 8510,8520,8530。

可以通过Nginx建了一个 TCP 负载均衡入口,即通过 8500 访问到 8510、8520、8530 三台consul服务器中。

server {
	listen 8500;
	location / {
		proxy_pass http://xdpconsul;
		proxy_redirect default;
	}
}

upstream xdpconsul {
	server 127.0.0.1:8510 weight=2;
	server 127.0.0.1:8520 weight=1;
	server 127.0.0.1:8530 weight=1;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/743324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-29
下一篇 2022-04-29

发表评论

登录后才能评论

评论列表(0条)

保存