注册中心——Consul小记

一、服务发现是什么?

1、服务发现

假如我需要用到A服务,而且其IP和port是稳定的,那么我在REST调用的时候就可以直接调用到该服务。所以,当网络环境是稳定的时候,想要调用多个服务,客户端只要知道它们的网络位置就可以了,以往的做法是在配置文件中配置,而且当网络环境发生变化的时候,需要改变每个调用者的配置。

客户端-------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。

此处因为本人的功力还不够,留坑后补。

 

参考:

服务发现 - consul 的介绍、部署和使用 

聊聊微服务的服务注册与发现

 

posted @ 2019-07-21 14:02  NYfor2018  阅读(652)  评论(0编辑  收藏  举报