注册中心——Consul小记
1、服务发现
客户端-------IP+port------>服务端1
-------IP+port------>服务端2
-------IP+port------>服务端N
但是,如果服务发现可以将服务端网络位置信息都集中起来,这样客户端可以根据想要调用的服务的名称,就可以获得其服务的IP和port。
客户端-------服务名------->服务发现<---------注册IP+port-----------服务端N
客户端<-----IP+port-------服务发现
为什么服务发现可以保存所有服务端的IP+port呢?因为内部有一张服务注册表,这是一个可用服务实例的数据库,服务注册表提供管理API和查询API功能,服务实例则使用管理API从服务注册表中注册和注销,系统组件使用查询API来发现可用的服务实例。
服务注册表的特性是高度可用和最新,eureka的做法是提供一个 用于注册和查询服务实例的REST API,服务实例使用POST请求注册其网络位置,每隔30s就使用PUT请求刷新其注册信息。而consul使用的是健康监测。
2、注册的IP和端口如何确定?
IP获取方式
以下是主流IP地址的获取方式:
-
手动配置需要注册的IP,也就是写配置文件,当然这种写死的方法在微服务中是不可行的,因为微服务基本都是支持水平扩容多机部署的,这种方法会带来运维上很多的不便。
-
通过遍历网卡的方式去获取,找到第一个不为本地环回地址的IP地址。
-
在一些网络规划比较好的标准化机房中,可以通过手动指定网卡名的方式,指定使用哪一块网卡所对应的的IP地址进行注册。
-
直接与服务注册中心建立socket连接,通过socket.getLocalAddress()方式获取本机IP。
端口获取方式
端口的获取方式,没有标准化方案。
-
如果是RPC应用,启动的时候都会有一个配置来指定服务监听端口,注册的时候可以直接使用配置项的端口值。
-
传统的WEB容器所提供的HTTP应用,也会有一个配置文件来配置容器的监听端口,注册时可以直接使用配置项的端口值。
-
在Java应用的SpringBoot框架中,可以通过(SpringBoot版本为1.x)EmbeddedServletContainerInitiallizedEvent.getEmbeddedServletContainer().getPort()来获取。
二、consul简介
1、什么是consul?
consul是一个支持多数据中心分布式可高用,用于服务发现和配置共享的工具,采用Raft算法保证服务的一致性,且支持健康检查。
2、consul关键特性
-
服务发现:通过DNS或HTTP方式获取服务信息。
-
健康检查:可以提供与给定服务相关联的任何数量的健康检查(如web状态码或cpu使用率)。
-
K/V存储:可以通过consul存储如动态配置之类的相关信息。
-
多数据中心:支持多数据中心,开箱即用。
-
WEB UI:通过web页面即可了解服务现在的运行情况,一目了然。
3、consul的原理
图中无论是CLIENT还是SERVER都算是一个节点,consul集群是由N个SERVER和M个CLIENT组成的。
-
CLIENT是consul的client模式,在这种模式下,所有注册到当前节点的服务都会被转发到SERVER,本身是不持久化这些信息。
-
SERVER是consul的server模式,功能与CILENT相同,但唯一不同的是它会将所有信息持久化到本地,这样遇到故障,信息是可以被保留并使用的。SERVER节点还参与Raft、维护会员信息、注册服务、健康检查等功能。
-
SERVER-LEADER表明它管理整个集群的SERVER,它负责同步注册的信息给其他SERVER,同时也要负责各个节点的健康检测。
-
LAN Gossip池包含了这个数据中心的所有节点,这样就不需要给客户端配置服务器地址,它可以自动完成,而且每个节点都可以进行节点故障检查,也可以进行事件广播。
-
WAN Gossip池包含了所有的SERVER(不包含CLIENT),这些服务器主要位于不同的数据中心,通常通过互联网或广域网进行通信。
consul需要有一个集群,通常3~5个SERVER节点,一个CLIENT通常带N个Service。Service到Consul可以通过HTTP API或者是直接写Consul配置文件的方式,CLIENT可以认为是无状态的,它将注册信息通过RPC转发到SERVER上,服务信息保存在SERVER的各个节点上,通过Raft实现强一致性。
如果Program要访问其他服务器上的Service,那么可以通过访问本机的CLIENT提供的HTTP API,本机CLIENT可以将请求转发到SERVER,SERVER查询到Service的当前信息后返回,最终Program可以获得Service所有的部署信息,然后就可以向Service的其中一个部署发送请求。
三、健康检查
1、consul的健康检查
consul中的agent是指节点(无论是CLIENT还是SERVER),consul提供Script/TCP/HTTP和Interval,以及TTL等方式,但是consul的健康检查主要是由服务注册的Agent来处理。但是有一个坏处是,consul发现节点挂掉后,服务的状态变为不可用了。
2、consul与Zookeeper、etcd区别
-
Zookeeper利用临时节点的机制,业务服务启动时创建临时节点,服务与节点共存亡。
-
etcd利用TTL机制,业务服务启动时创建键值对,定时更新TTL,TTL过期服务不可用。
Zookeeper和etcd的键值存储都是强一致性的,键值对会自动同步到多个节点,只要某个节点上存在就可以认为对应的业务服务是可用的。
Consul的数据同步也是强一致性的,服务的注册信息会在SERVER节点之间同步,相比起ZK、etcd,服务信息是持久化的,即使服务部署不可用了,依然可以查询到这个服务部署。但是业务服务的可用状态是由注册到的Agent决定的,如果Agent无法正常工作,则无法确定服务的真实状态,当然,这个Agent挂掉了,其他Agent来接管也不管用,因为Agent挂掉的话也说明这个服务器的状态可能也不太好,此时屏蔽掉此节点啥和功能的服务也是合理的。
3、健康检查方式
服务的健康检查分为客户端心跳和服务端主动探测两种方式
1) 客户端心跳
-
客户端每隔一定时间主动发送“心跳”的方式来向服务端表明自己的服务状态正常,心跳可以是TCP的形式,也可以是HTTP的形式。
-
维持客户端和服务端的socket长连接,自己实现一个客户端心跳。
-
Zookeeper没有主动发送心跳,而是依赖组件本身提供的临时节点的特性,通过Zookeeper连接的session来维持临时节点。
但是客户端心跳中,长连接的维持和客户端的主动心跳都只是表明链路上的正常,不一定是服务状态正常。
2) 服务端主动探测
-
服务端调用服务发布者某个HTTP接口来完成健康检查。
-
对于没有提供HTTP服务的RPC应用,服务端调用服务发布者的接口来完成健康检查。
-
可以通过执行某个脚本的形式来进行综合检查。
但是服务端主动监测也存在问题。服务注册中心主动调用RPC服务的某个接口无法做到通用性;在很多场景下服务注册中心到服务发布者的网络是不同的,服务端无法主动发起健康检查。
四、consul安全
consul由于采用了gossip机制、RPC系统、HTTPS来提供功能,这两种系统采用的安全机制不同,其中gossip使用对称密钥提供加密,RPC则可以使用客户端认证的端到端TLS,HTTPS 也是使用客户端认证的端到端 TLS。
此处因为本人的功力还不够,留坑后补。
参考: