其他分享
首页 > 其他分享> > Consul作为注册中心在云环境的实践与应用

Consul作为注册中心在云环境的实践与应用

作者:互联网

前言

本文主要介绍Consul作为注册中心在『云』环境的实践与应用。开始本文介绍之前,首先会简单介绍注册中心基础知识以及相关理论,以便读者更好的理解,随后会重点介绍在『云』环境中使用Consul作为注册中心的实践经验。

注册中心介绍

在微服务架构流行之前,注册中心就已经出现在分布式架构的系统中,随着近些年微服务架构越来越受到开发者的青睐以及云原生理念逐步被开发者接受,注册中心作为微服务架构中最核心的基础设施之一,其重要性不言而喻。

什么是注册中心

在介绍什么是注册中心之前,我们先看一个现实中的例子,相信大家都是用过手机通讯录,我们以此为例:

上述两个场景,其实跟微服务场景中的两个概念非常贴切:

相信大家都已经理解了这个现实场景,我们再对注册中心做以下说明,注册中心最本质的功能可以看成是一个函数:

# service-name服务名为查询参数,Result代表可用的 endpoints (ip:port) 列表为返回值
Result = F(service-name)

为什么需要注册中心我们还是以上面的例子为例,我相信在实际生活中应该不会有人会记住每个同事的电话号码,况且同事的电话号码可能会发生变化,因此通过这种方式会显得不切合实际,我们只需要记住同事的名字即可,通过同事的名字查询其对应电话号码。相信到这里读者已经发现为什么需要注册中心了。我们在回到分布式架构中,服务调用方只需要记住需要调用服务的逻辑名称即可,可以通过注册中心查询其逻辑名称对应的服务地址。在实际实践过程中还会发现很多问题,如下:

这里问题的解决都依赖于注册中心。简单看,注册中心的功能有点类似于DNS服务器或者负载均衡器,而实际上,注册中心作为微服务的基础组件,可能要更加复杂,也需要更多的灵活性和时效性。

主流注册中心

上面介绍了很多注册中心的基础知识,下面我们重点介绍下目前市面上的主流注册中心:

对于上述注册中心的各项对比,并不是本文的重点,相信各位读者都会根据各自的实际情况选择不同的注册中心,我们重点介绍Consul作为注册中心的实践与应用。

理论

分布式基础理论

相信很多熟悉分布式系统设计的读者都知道CAP理论,CAP理论告诉我们一个分布式系统不可能同时满足一致性(C: Consistency)、可用性(A: Availability)和分区容错性(P: Partition tolerance)。其中这三点主要描述了:

后来,又出现了BASE理论,BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致)三个短语的缩写,其中最终一致性指的是系统中的所有数据副本,在一段时间的同步后,最终能够达到一个一致的状态,因此最终一致性的本质是需要系统保证最终数据能够一致,而不是需要实时保证系统数据的强一致性。

一致性算法Raft

讲了这么多,我们主要为了引出分布式一致性算法。分布式一致性算法允许一组机器像一个整体一样工作,即使其中一些机器出现故障也能够继续工作。为了解决分布式一致性问题,在长期的探索研究中,涌现了一批经典的一致性协议和算法,其中比较著名的是两阶段提交协议三阶段提交协议PaxosZAB、Raft等。下面我们主要介绍Raft共识算法,其一开始就被设计成一个易于理解和实现的算法;Consul中也是使用Raft协议作为其一致性算法,其他一致性协议有兴趣的读者也可以查阅相关资料。为了提高可理解性,Raft将一致性算法分解为几个关键的模块,下面主要介绍两个重要模块:领导人选举(leader election)、日志复制(Log replication)。Raft一致性算法在许多方面和现在的一致性算法很相似,但是它有一些独特的特性:

节点状态

Raft中规定的节点类型包括了:跟随者(Follower)、竞选者/参选者(Candidate)和领导者(Leader)。

图:节点状态变化,Follower仅响应其他节点的请求。当follower在一段时间内未接收到请求时,则会变为Candidate初始化一轮选举。当Candidate接收到集群中的半数以上节点的响应后则会变为leader。Leader执行处理逻辑直到它失败;

注 本图来源于论文《In Search of an Understandable Consensus Algorithm》Figure 4;

复制状态机(Replicated state machines)

一致性算法是从复制状态机的背景下提出的。在这种算法中,一组服务器上的状态机产生相同状态的副本,并且在一些机器宕掉的情况下也可以继续运行。

图 复制状态机的结构。一致性算法管理着来自客户端指令的复制日志。状态机从日志中处理相同顺序的相同指令,所以产生的结果也是相同的。注 本图来源于论文《In Search of an Understandable Consensus Algorithm》Figure 1复制状态机通常都是基于复制日志实现的,如上图。每一个服务器存储一个包含一系列指令的日志,并且按照日志的顺序进行执行。每一个日志都按照相同的顺序包含相同的指令,所以每一个服务器都执行相同的指令序列。因为每个状态机都是确定的,每一次执行操作都产生相同的状态和同样的序列。保证复制日志相同就是一致性算法的工作了

领导选举(leader election)

初始Follower状态Raft使用一种心跳机制来触发领导人选举,当节点启动时,其状态都为follower。一个节点继续保持follower状态直到其能够从Leader或者Candidate处收到有效的RPC请求。Leader周期性的向所有的follower发送心跳包(Empty AppendEntry)来维持自己的权威性。如果一个跟随者在一段时间内没有接收到任何消息,这就是选举超时,它会认为系统中没有可用的leader,则会发起选举选出新的leader。Follower转换为Candidate状态一次选举过程,Follower需要先增加自己当前的任期号并且转换为Candidate。然后它并行的向集群中的其他节点发送请求投票(Request Vote)的RPC请求来给自己投票。Candidate继续保持该状态直到这三件事情之一发生:

Candiate转为Leader状态当一个Candidate从整个集群中大多数节点获取了针对同一任期号的投票,则它赢得这次选举并成为leader。每个节点最多能够对一个任期号投出一张选票,并且按照先来先服务的原则。针对平等瓜分选票(这也是集群选择奇数个节点的原因):Candidate既没有赢得选举也没有输:如果有多个Follower同时成为候选人,那么选票可能会被瓜分以至于没有Candidate可以赢得大多数人的支持。当这种情况发生的时候,每一个候选人都会超时,然后通过增加当前任期号来开始一轮新的选举。Raft 算法使用随机选举超时时间的方法来确保很少会发生选票瓜分的情况,就算发生也能很快的解决。每一个候选人在开始一次选举的时候会重置一个随机的选举超时时间,然后在超时时间内等待投票的结果,这样减少了在新的选举中出现选票瓜分的可能性。推荐读者可以参考动图了解该部分具体实现,这有助于读者更好的了解其实现:http://thesecretlivesofdata.com/raft/

日志复制(Log Replication)

图:日志复制

Raft 协议强依赖 Leader 节点来确保集群数据一致性,具体的处理流程:

Consul注册中心实践与应用

Consul介绍

Consul是HashiCorp推出的一款品,其是一个service mesh解决方案,提供了功能丰富的控制面功能:service discovery、configuration以及segmentation functionality。这些功能可以根据需要独立使用,或者将它们一起使用用来构建完整的service mesh。Consul提供的关键功能如下:

更多详细内容,读者可参考:https://www.consul.io/intro/index.html架构设计如下图:

图:Consu架构设计;

为方便读者理解,对相关术语进行说明:

Raft In Consul

更加详细说明请参考:参考:https://www.consul.io/docs/internals/consensus.html

实践与应用

介绍了这么多理论知识有助于我们理解后文的实践,接下来我们开始介绍其实践与应用;

架构设计

图:云环境架构设计;

注册中心作为基础组件,其自身的可用性显得尤为重要,高可用的设计需要对其进行分布式部署,同时因分布式环境下的复杂性,节点因各种原因都有可能发生故障,因此在分布式集群部署中,希望在部分节点故障时,集群依然能够正常对外服务。Consul使用Raft协议作为其分布式一致性协议,本身对故障节点有一定的容忍性,在单个DataCenter中Consul集群中节点的数量控制在2*n + 1个节点,其中n为可容忍的宕机个数。我们在设计时采用同Datacenter集群内部部署3个Server节点,来保障高可用性,当集群中1个节点发生故障后,集群仍然能够正常运行,同时这3个节点部署在不同的机房,达到机房容灾的能力。若读者对Raft协议中日志复制(Log Replication)熟悉则会更加轻松的理解对于该节点数量设计,读者也可参考Consul官网对部署的说明。在云上环境,涉及多region环境,因此在架构设计设计时,我们首先将Consul的一个Datacenter 对应云上一个region,这样更符合Consul对于Datecenter的定义(DataCenter数据中心是私有性、低延迟、高带宽的网络环境)。中间代理层(Proxy Layer):实现服务鉴权、多租户隔离等功能。

云原生实践

服务注册

服务注册接口

MethodPathProduces
{
  "ID": "instance-test-default-provider-demo-172-22-204-39-provider-demo-10001",
  "Name": "provider-demo",
  "Tags": [
    ""
  ],
  "Address": "172.22.204.39",
  "Port": 10001,
  "Meta": {                          # 相关meta信息
    "key1": "value1"
  },
  "Check": {
    "TTL": "30s",                          # TTL健康检查
    "deregisterCriticalServiceAfter": "30s"  # 异常服务下线
  }
}

健康检查

Consul提供多种多样的健康检查方式,可以分为:

结合云上的实际情况,包括底层依赖和网络环境,采用Time To Live(TTL)方式作为服务健康检查方式,即由业务方应用定期向注册中心汇报状态,此处进行两点说明:

更多健康检查细节,读者可参考:https://www.consul.io/docs/agent/checks.html

多租户

云上环境存在多租户隔离的需求,即:

针对此场景,需要在 『中间代理层』完成对多租户隔离功能的实现,其主要实践思路为,使用Consul Api Feature 具备 Filtering功能:

利用Filtering特性,可以自定义Filtering表达式,可实现绝大多数的逻辑运算,因此在实践过程中,服务注册时,会将租户信息存储在Meta信息中,查询时采用该信息实现Filtering 表达式,具体的例子如下所示:

$ curl -G http://localhost:8500/v1/agent/services --data-urlencode 'filter=Meta.tenant==test'

更多Filtering细节,读者可参考:https://www.consul.io/api/features/filtering.html

鉴权认证

在实际的应用场景,我们需要保证数据的安全性,主要的要求我们可以总结为2点:

key_prefix "test" {
   policy = "read"
}

数据同步

图:跨Datacenter(Region)数据同步;

在实际的实践的过程中,我们发现需要跨Datacenter的场景会分为以下几个方面:

容灾

注册中心作为微服务基础设施,因此对其容灾和其健壮性有一定的要求,主要体现在:

服务端容灾

图:Datacenter设计;

Consul使用Raft协议作为其分布式一致性协议,本身对故障节点有一定的容忍性,在单个DataCenter中Consul集群中节点的数量控制在2*n + 1个节点,其中n为可容忍的宕机个数。Consul官网对每个Datacenter集群中可容忍的故障节点个数进行了说明:

Servers数量Quorum Size(半数节点)Failure Tolerance(可容忍故障数)

基于上述表格中可容忍的故障数同时结合实际的场景需求,设计在Datacenter中部署3个Consul Server节点。可能有读者有疑问:Q1: 节点的个数是否可以为偶数个? 答案是 可以的,但是不建议部署偶数个节点,一方面如上表中偶数节点4和奇数节点3可容忍的故障数是一样的,另一方面,偶数个节点在选主节点的时候可能会出现 瓜分选票的情形(虽然Consul通过重置election timeout来重新选举),但是还是建议选取奇数个节点。Q2: 是不是Server节点个数越多越好? 答案是 否定的,虽然上表中显示Server数量越多可容忍的故障数越多,熟悉Raft协议的读者肯定熟悉 Log Replication如上文介绍(日志复制时过半写成功才返回写成功),随着Server的数量越来越多,性能就会越低,所以结合实际场景一般建议Server部署3个节点。 若读者对Consul中的Consensus有兴趣,可参考:https://www.consul.io/docs/internals/consensus.htm

客户端容灾

图:客户端容灾;

注册中心设计的一个重要前提是:注册中心不能因为自身的原因或故障影响服务之间的相互调用。因此在实践过程中,如果注册中心本身发生了宕机故障/不可用,绝对不能影响服务之间的调用。这要求对接注册中心的SDK针对这种特殊情况进行客户端容灾设计,『客户端缓存』就是一种行之有效的手段。当注册中心发生故障无法提供服务时,服务本身并不会更新本地客户端缓存,利用其已经缓存的服务列表信息,正常完成服务间调用。

讲到这里,本文的整体内容就已经讲述完了,文中很多知识点只是进行了简单介绍,更深入的还需读者可进一步查阅相关资料,望本文能够让读者对 Consul作为注册中心及其实践有进一步认识和理解。

附录

  1. raft共识算法介绍:https://raft.github.io/
  2. 《In Search of an Understandable Consensus Algorithm》:https://raft.github.io/raft.pdf
  3. Raft动画:http://thesecretlivesofdata.com/raft/
  4. Raft交互式动画:https://raft.github.io/raftscope/index.html

了解更多微服务、云原生技术的相关信息,请关注我们的微信公众号【云原生计算】!

 

标签:Datacenter,Consul,实践,注册,一致性,Raft,节点
来源: https://blog.csdn.net/yunyuansheng/article/details/113517682