SpringCloud微服务注册中心Consul

前言

SpringCoud核心组件中一文,首先提到了SringCoud注册中心Eureka,后台Eureka官方已不再维护,于是有了Eureka的替代方案Consul,下面具体说一下Consul注册中心。

一、Consul服务注册中心的整体架构

1、consul内部原理

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

在单个数据中心中,Consul分为Client和Server两种节点(所有的节点都具备Agent的功能)。

  1. Consule Server节点:保存整个集群的数据,
  2. Consule Client负责健康检查及转发数据请求到Server(Client节点当然也保存注册到本节点的服务数据);
  3. 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集群。
(1)、服务器Server1、Server2、Server3上分别部署了Consul Server,假设通过选举,得到Server2上的Consul Server节点为Leader,其它为Follower。

(2)、服务器Server4和Server5上,通过Consul Client分别注册微服务A、B、C,这里每个微服务分别部署在了两个服务器上

微服务注册到Consul方式:

  • 可以通过HTTP API(8500端口)的方式,
  • 也可以通过Consul配置文件的方式。

Consul Client会将注册信息通过RPC转发到Consul Server,服务信息保存在Server的各个节点中,并且通过Raft实现了强一致性;
Consul Client还会对注册到当前节点的服务进行健康检查,并将服务状态同步到Server,当然也是强一致性的。

(3)、服务器Server6中微服务 D需要访问微服务B,这时候微服务D首先访问本机Consul Client提供的HTTP API,本机Client会将请求转发到Consul Server,Consul Server查询到微服务 B当前的信息返回,最终微服务D拿到了微服务B的所有部署的IP和端口,然后就可以选择微服务B的其中一个部署并向其发起请求了。

3、docer安装consul

安装Docker

通过这个地址下载安装:
https://store.docker.com/editions/community/docker-ce-desktop-windows
安装完成后打开 Windows PowerShell,输入docker –version,如果正常输出docker版本就可以了。

启动Consul集群

在 Windows PowerShell中执行命令拉取最新版本的Consul镜像:

docker pull consul

然后就可以启动集群了,这里启动4个Consul Agent(3个Server,1个Client)。3个Server中会选举出一个leader。

#启动第1个Server节点,集群要求要有3个Server,将容器8500端口映射到主机8900端口,同时开启管理界面
docker run -d --name=consul1 -p 8900:8500 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --bootstrap-expect=3 --client=0.0.0.0 -ui

#启动第2个Server节点,并加入集群
docker run -d --name=consul2 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.2

#启动第3个Server节点,并加入集群
docker run -d --name=consul3 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.2

#启动第4个Client节点,并加入集群
docker run -d --name=consul4 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=false --client=0.0.0.0 --join 172.17.0.2

第1个启动容器的IP一般是172.17.0.2,后边启动的几个容器IP会排着来:172.17.0.3、172.17.0.4、172.17.0.5。

进入容器consul1:

docker exec -it consul1 /bin/sh

#执行ls后可以看到consul就在根目录
ls

输入exit可以跳出容器。

4、Consul的健康检查

Consul做服务发现是专业的,健康检查是其中一项必不可少的功能,其提供Script/TCP/HTTP+Interval,以及TTL等多种方式。服务的健康检查由服务注册到的Agent来处理,这个Agent既可以是Client也可以是Server。

集中式的心跳机制,比如传统的Eureka,是让各个服务都必须每隔一定时间发送心跳到Eureka Server。
如果一段时间没收到心跳,那么就认为这个服务宕机了。

但是这种集中式的心跳机制会对Eureka Server造成较大的心跳请求压力,实际上平时Eureka Server接收最多的请求之一就是成千上万服务发送过来的心跳请求。

所以Consul在这块进行了架构优化,引入了Agent概念
每个机器上的Consul Agent会不断的发送请求检查服务是否健康,是否宕机。如果服务宕机了,那么就会通知Consul Server。

Consul与ZooKeeper、etcd的区别

后边这两个工具是通过键值存储来实现服务的注册与发现。

  • ZooKeeper利用临时节点的机制,业务服务启动时创建临时节点,节点在服务就在,节点不存在服务就不存在。
  • etcd利用TTL机制,业务服务启动时创建键值对,定时更新ttl,ttl过期则服务不可用。

健康检查能不能支持故障转移?

上边提到健康检查是由服务注册到的Agent来处理的,那么如果这个Agent挂掉了,会不会有别的Agent来接管健康检查呢?答案是否定的

5、Consul的其它部署架构

如果你实在不想在每个主机部署Consul Client,还有一个多路注册的方案可供选择,这是交流群中获得的思路

在这里插入图片描述
如图所示,在专门的服务器上部署Consul Client,然后每个服务都注册到多个Client,这里为了避免服务单点问题还是每个服务部署多份,需要服务发现时,程序向一个提供负载均衡的程序发起请求,该程序将请求转发到某个Consul Client。这种方案需要注意将Consul的8500端口绑定到私网IP上,默认只有127.0.0.1。

这个架构的优势:

  • Consul节点服务器与应用服务器隔离,互相干扰少;
  • 不用每台主机都部署Consul,方便Consul的集中管理;
  • 某个Consul Client挂掉的情况下,注册到其上的服务仍有机会被访问到;

但也需要注意其缺点:

  • 引入更多技术栈:负载均衡的实现,不仅要考虑Consul Client的负载均衡,还要考虑负载均衡本身的单点问题。
  • Client的节点数量:单个Client如果注册的服务太多,负载较重,需要有个算法(比如hash一致)合理分配每个Client上的服务数量,以及确定Client的总体数量。
  • 服务发现要过滤掉重复的注册,因为注册到了多个节点会认为是多个部署(DNS接口不会有这个问题)。

这个方案其实还可以优化,服务发现使用的负载均衡可以直接代理Server节点,因为相关请求还是会转发到Server节点,不如直接就发到Server。

是否可以只有Server?

这个问题的答案还是有关服务数量的问题,首先Server的节点数量不是越多越好,3个或者5个是推荐的数量,数量越多数据同步的处理越慢(强一致性);然后每个节点可以注册的服务数量是有上限的,这个受限于软硬件的处理能力。所以如果你的服务只有10个左右,只有Server问题是不大的,但是这时候有没有必要使用Consul呢?因此正常使用Consul的时候还是要有Client才好,这也符合Consul的反熵设计。

大家可以将这个部署架构与前文提到的普适架构对比下,看看哪个更适合自己,或者你有更好的方案欢迎分享出来。

6、Consul如何通过Raft协议实现强一致性?

首先,Consul Server是部署集群的,而且他会选举出来一台Server作为Leader。

接下来各个服务发送的注册请求都会落地给Leader,由Leader同步给其他Follower。

所以首先第一点,Leader Server是绝对有最新的服务注册信息的。

比如库存服务发起注册了,那么Leader Server上一定有库存服务的注册信息。

接着如果比如订单服务要发现库存服务的话,这个查询请求会发送给Leader Server。

这样服务注册和发现,都是通过一台Leader Server来进行的,就可以保证服务注册数据的强一致性了,大家看下图。

假如库存服务在注册的时候数据刚写到Leader Server,结果Leader Server就宕机了?

那么此时这条注册数据就丢失了,订单服务就没法发现那个库存服务了。没关系,这里Consul会基于Raft协议来解决这个问题。

首先,库存服务注册到Leader Server的时候,会采取Raft协议,要求必须让Leader Server把这条注册数据复制给大部分的Follower Server才算成功。

这就保证了,如果你认为自己注册成功了,那么必然是多台Consul Server都有这条注册数据了。

如果你刚发送给Leader Server他自己就宕机了,那么这次注册会认为失败。

此时,Consul Server集群会重新选举一个Leader Server出来,你需要再次重新注册。

这样就可以保证你注册成功的数据绝对不会丢,然后别人发现服务的时候一定可以从Leader Server上获取到最新的强一致的注册数据。
原文:

http://blog.bossma.cn/consul/consul-service-register-and-discovery-style/

https://mp.weixin.qq.com/s?__biz=MzU0OTk3ODQ3Ng==&mid=2247484680&idx=1&sn=d25e1f81ad75f68dd88755173843efad&chksm=fba6ed0bccd1641d7edfd05431904b96f2e3da7c04b3a75c2a350e374733f59971c01ddd9ae6&scene=21#wechat_redirect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值