深入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。
问题解答
是否可以只有Server?
这个问题的答案还是有关服务数量的问题,首先Server的节点数量不是越多越好,3个或者5个是推荐的数量,数量越多数据同步的处理越慢(强一致性);然后每个节点可以注册的服务数量是有上限的,这个受限于软硬件的处理能力。所以如果你的服务只有10个左右,只有Server问题是不大的,但是这时候有没有必要使用Consul呢?因此正常使用Consul的时候还是要有Client才好,这也符合Consul的反熵设计。
基本原理
首先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端口完成。
服务发现原理
图解
这是一个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等注册发现原理!