深入Consul及相关性原理

405 阅读6分钟

深入Consul及相关性原理

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

问题抛出,当日常工作使用Consul越来越频繁之后,不由就会对使用的这个服务发现组件进行思考,为什么使用?难道就只是注册一下服务吗!它到底有多好用,工作才一直使用它,它是如何工作的。下面抛出几个问题之后再进入本文进行阅读:

服务注册到节点后,其他节点为什么没有同步?
Raft协议强一致性同步,这次不同步,下一次也会同步
Client是干什么的?(Client有什么作用?)
RPC转发,健康检查,
能不能直接注册到Server?(是否只有Server节点就够了?)否,Client RPC转发到Server
服务信息是保存在哪里的?Client
如果节点挂了健康检查能不能转移到别的节点? 否定

为什么使用

伴随着服务大量出现,治理起来比较困难,需要一个能够协调和统一管理服务的中间件,那就是服务注册中心,常见的有Etcd,zk,Eureka,Consul等,能够解决在微服务中访问和检查等难题!

在这里我建议可以先看一下raft协议,这位老哥写的还不错!

http://124.223.167.77/archives/raft

如果是想看Consul的基本概念和使用,请看:

http://124.223.167.77/archives/consul

在这里插入图片描述

Gossip算法

要先研究Consul那么就需要先知道raft协议Gossip算法.

Gossip是一个最终一致性算法。

Gossip算法如其名,灵感来自办公室八卦,只要一个人八卦一下,在有限的时间内所有的人都会知道该八卦的信息

Gossip的特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的,当然这也是疫情传播的特点。

要注意到的一点是,即使有的节点因宕机而重启,有新节点加入,但经过一段时间后,这些节点的状态也会与其他节点达成一致,也就是说,Gossip天然具有分布式容错的优点。

服务注册流程

1、当 Producer 启动的时候,会向 Consul 发送一个 post 请求,告诉 Consul 自己的 IP 和 Port;

2、Consul 接收到 Producer 的注册后,每隔 10s(默认)会向 Producer 发送一个健康检查的请求,检验 Producer 是否健康;

3、当 Consumer 发送 GET 方式请求 /api/address 到 Producer 时,会先从 Consul 中拿到一个存储服务 IP 和 Port 的临时表,从表中拿到 Producer 的 IP 和 Port 后再发送 GET 方式请求 /api/address

4、该临时表每隔 10s 会更新,只包含有通过了健康检查的 Producer。

image-20220408103358393

问题解答

是否可以只有Server?

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

基本原理

image-20220408104126950

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

在单个数据中心中,Consul分为Client和Server两种节点(所有的节点也被称为Agent),Server节点保存数据,Client负责健康检查及转发数据请求到Server;Server节点有一个Leader和多个Follower,Leader节点会将数据同步到Follower,Server的数量推荐是3个或者5个,在Leader挂掉的时候会启动选举机制产生一个新的Leader😶‍🌫️(raft协议选举)。

集群内的Consul节点通过gossip协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在还有哪些节点,这些节点是Client还是Server。单个数据中心的流言协议同时使用TCP和UDP通信,并且都使用8301端口。跨数据中心的流言协议也同时使用TCP和UDP通信,端口使用8302。

集群内数据的读写请求既可以直接发到Server,也可以通过Client使用RPC转发到Server,请求最终会到达Leader节点,在允许数据轻微陈旧的情况下,读请求也可以在普通的Server节点完成,集群内数据的读写和复制都是通过TCP的8300端口完成。

服务发现原理

image-20220408104851225

图解

这是一个Consul集群,Server和Leader

分别在五台机器上部署了Consul

这里有四个服务A,B,C,D,ABC服务同时注册在Server4和Server5上面,因为某种原因保证了多点集群,防止单机问题!

服务注册到Consul可以通过HTTP API(8500端口)的方式,也可以通过Consul配置文件的方式。Consul Client可以认为是无状态的,它将注册信息通过RPC转发到Consul Server,服务信息保存在Server的各个节点中,并且通过Raft实现了强一致性。所以Server 1-3间是绿色,共享了注册信息.

服务间的发现和调用流程

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和端口

最后

优秀的工程师不应该停步不前,学会举一反三,去掌握ZK,Etcd等注册发现原理!