注册中心Consul产线部署架构

1,767 阅读3分钟

1、Consul官方架构图和说明

Consul 提供了高可用的kv存储,集群架构,这点和etcd zookeeper类似。 另外也提供了自动服务发现注册的套件,并且能否对服务进行健康检查。 结合consul-template可以实现服务提供方信息更新(比如增加了API服务器)时,自动生成配置文件给服务使用方自动更新配置。

从图中可看到的是Consul支持跨数据中心,在每个数据中心有client和server。一般server是3-5个,少了会影响可靠性,多了会影响速度。client则没有数量的限制。

集群通过goosip协议管理所有node成员和广播集群消息,client需要配置文件就能发现急群众所有的server,节点故障检测被分不到整个集群,不需要server的参与。所有server通过Raft协议进行选主(leader), leader负责处理所有的查询和事务。

server还负责与其他数据中心交互来处理跨数据中心的请求,当server收到这种请求它会将请求转发到相应的数据中心活本地的leader。

2、纯Server模式

client和server本质都是consul的agent,只是角色不同(在启动时指定参数即可)。之前我们产线环境并没有完全按照官方架构图(即client-server模式)进行部署,而是采用了全部server的模式,如下图:

3、纯Server模式带来的问题

这种架构下带来的问题有两个:

  1. 高可用
    服务实例注册时配置的consul-host是负载均衡的地址,服务注册到集群中后,由集群中的一个节点负责对该实例进行健康检查。假如存在一下情况:(1)某个服务有两个节点实例,这两个节点通过负载均衡进行注册后都由server1进行健康检查(2)server1节点不可用(可能是server1挂了,也可能是server1所在机器出现问题)。这样就会导致服务在注册中心中消失导致服务无法访问到,而服务本身并不存在问题。
  2. 服务注销
    因为集群中的某一个节点(比如server1)负责服务的健康检查,在服务从注册中心注销时,通过负责均衡注销时的代码如下:
ConsulClient client = new ConsulClient("负载均衡地址");
client.agentServiceDeregister("当前服务在注册中心的Id");

由于负载均衡,注销时定位到的集群节点可能是server2,这样就会导致服务的注销失败。解决的办法是遍历集群中的所有节点(members)进行注销,具体可参考:使用Consul时,服务无法正常注销

4、用Client-Server模式

目前consul的整体架构升级为client-server模式,服务注册时不再向consul-server集群进行注册,而是向服务所在机器的consul-client进行注册,有consul-client将注册信息同步到consul-server集群中,架构如下:

回顾以上两个问题:

  1. 高可用
    服务实例注册时向本级consul-client进行注册,如果consul-client不可用,只影响这个consul-client所在机器的所有服务实例(如果机器挂了则所有这台机器上的实例不能访问就很合理)。因为服务实例本身的高可用会分布在不同的机器上,所以不会影响另外一台机器上的实例(不要把鸡蛋放在一个篮子里)。

注意:consul-client挂了,服务的注册信息不会转移到另外一个consul-client中。所以要求服务本身处于不同的机器上来保证高可用。

  1. 服务注销
    服务从注册中心注销时,只需要连接到本地的consul-client进行注销即可,一台机器就一个consul-client,不需要经过负载均衡:
ConsulClient client = new ConsulClient("local-consul-client-ip");
client.agentServiceDeregister("当前服务在注册中心的Id");