从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后来逐步应用于生产环境,并总结了少许使用经验。最开始使用Consul的人不多,为了方便交流创建了一个QQ群(群号在最后),这两年微服务越来越火,使用Consul的人也越来越多,目前群里已有400多人,经常有人问一些问题,比如:
服务注册到节点后,其他节点为什么没有同步?
Client是干什么的?(Client有什么作用?)
能不能直接注册到Server?(是否只有Server节点就够了?)
服务信息是保存在哪里的?
如果节点挂了健康检查能不能转移到别的节点?
有些人可能对服务注册和发现还没有概念,有些人可能使用过其它服务发现的工具,比如zookeeper,etcd,会有一些先入为主的经验。这篇文章将结合Consul的官方文档和自己的实际经验,谈一下Consul做服务发现的方式,文中尽量不依赖具体的框架和开发语言,从原理上进行说明,希望能够讲清楚上边的几个问题。
为什么使用服务发现
防止硬编码、容灾、水平扩缩容、提高运维效率等等,只要你想使用服务发现总能找到合适的理由。
一般的说法是因为使用微服务架构。传统的单体架构不够灵活不能很好的适应变化,从而向微服务架构进行转换,而伴随着大量服务的出现,管理运维十分不便,于是开始搞一些自动化的策略,服务发现应运而生。所以如果需要使用服务发现,你应该有一些对服务治理的痛点。
但是引入服务发现就可能引入一些技术栈,增加系统总体的复杂度,如果你只有很少的几个服务,比如10个以下,并且业务不怎么变化,吞吐量预计也很稳定,可能就没有必要使用服务发现。
Consul内部原理
下面这张图来源于Consul官网,很好的解释了Consul的工作原理,先大致看一下。
![](https://i-blog.csdnimg.cn/blog_migrate/7f31d167b49f98d88030d1c6c3d9c760.jpeg)
首先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端口完成。
Consul服务发现原理
下面这张图是自己画的,基本描述了服务发现的完整流程,先大致看一下。
![](https://i-blog.csdnimg.cn/blog_migrate/f7fd3abcf9dc07b7503205df7b8264b4.png)
首先需要有一个正常的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可以认为是无状态的,它将注册信