分布式下的服务发现

  • 什么是服务发现

首先,服务发现中有三个角色:服务提供者、消费者、中介;以租房的过程为例:房东座位服务提供者,将房屋信息(服务地址)在中介机构注册登记;租房人在中介查找自己想要住的地址,然后根据地址所匹配的服务去消费;中介提供了多个服务,每个服务也由多个服务提供者提供。服务中介就像字典,包含多喝k-v键值对,分别对应服务名和服务提供者的地址列表。服务注册向字典中put键值对,服务发现就是根据服务名查找服务地址即getValue(k),根据特定的K来获取我们所需要的服务。服务发现的过程就是程序如何通过一个K来获取服务列表,并且这个服务列表是能够随着服务的状态而动态变更的。分布式系统中所有服务的信息都由服务发现组件记录。

当服务提供者节点挂掉时,服务需要及时取消注册并且通知消费者重新获取服务地址。不然就相当于服务中介中存在了一个黑地址,指向了一个不存在的服务。这时需要引入服务保活和检查机制。服务提供者需要每隔5秒左右向服务中介汇报存活,服务中介也需要记录服务地址和汇报时间。每隔10秒记录,踢掉汇报时间严重落后的服务地址项。以保证服务列表中服务地址的有效性。

当服务提供者新加入时,服务中介要及时告知服务消费者,有新的服务。可以采用轮询,消费者需要每隔几秒查询服务列表是否有改变。如果服务很多,服务列表很大,消费者很多可以引入服务列表的版本号机制,给每个服务提供一个key/value设置服务的版本号,在服务列表发生变动时,递增这个版本号。消费者只需要轮询这个版本号的变动即可知道服务列表是否发生了变化。采用pubsub。这种方式及时性要明显好于轮询。使用单个pubsub广播全局版本号的变动。接收到版本变动的消费者再去检查各自的依赖服务列表的版本号是否发生了变动。这种全局版本号也可以用于第一种轮询方案。

  • 服务发现模式

服务发现主要有两种实现方式:自理式和代理式(也叫客户端发现模式和服务端发现模式)。

自理式结构就是指每个微服务自己完成服务发现。每个微服务自己到服务中心查询服务列表,根据自己的负载均衡策略调用不同的服务地址。由于每个微服务都承担了服务发现的功能,访问压力分散到了各个微服务节点,性能和可用性上不存在明显的压力和风险。缺陷是它将客户端与服务注册中心耦合在一起。必须为服务客户端使用的每种编程语言和框架都实现服务发现逻辑;

代理式结构就是指微服务之间有一个负载均衡系统,由负载均衡系统来完成微服务之间的服务发现。

代理式的方式看起来更加清晰,微服务本身的实现也简单了很多,但实际上这个方案风险较大。第一个风险是可用性风险,一旦负载均衡系统故障,就会影响所有微服务之间的调用;第二个风险是性能风险,所有的微服务之间的调用流量都要经过负载均衡系统,性能压力会随着微服务数量和流量增加而不断增加,最后成为性能瓶颈。因此负载均衡系统需要设计成集群的模式,但LOAD BALANCER集群的实现本身又增加了复杂性。

  • Raft算法

由于Paxos算法过程许多人难以理解,Raft算法从设计之初,就将Understandable作为最高准则。下面从几个方面简单描述raft算法:

1.角色

首先在一个由 Raft 协议组织的集群中有三类角色:Leader(领袖)、.Follower(群众)、Candidate(候选人)

2.总体描述

在初始阶段并没有领袖,则所有群众都可以成为候选人进行选举,选举结束后选出领袖,其他候选人又再次成为群众的角色。每个领袖都有自己的任期(Term)。

3.leader的选举

那么接下来我们来看选举过程,在一个集群中至少需要三个元素才可以投出多数票,以A、B 、C三个元素为例,当有任意一个元素得到2票时即成为领袖。若三人都各获得一票,则每个参与方随机休息一阵,进入一个随机的timeout时间。最先从timeout中恢复的一方向其他两方请求投票直到有一方获得多数票。

选出 Leader 后,Leader 通过定期向所有 Follower 发送心跳信息维持其统治。若 Follower 一段时间未收到 Leader 的心跳则认为 Leader 可能已经挂了再次发起选主过程。

4.数据的传输

客户端发送的数据都必须经过leader节点,leader接收到数据后向follower复制一份数据(数据未未提交状态),follower接收到数据后向leader发送确认信息,当leader收到过半数的确认后向客户端发送ack响应,表明此时数据进入已提交状态,再向follower节点发送数据已提交通知。

5.Leader节点对数据一致性的影响

在客户端发送数据时、leader向follower复制数据时,若leader挂掉,由于客户端未收到ack将会进行重发,新的leader被选举出来后会要求follower数据与它保持一致。

当leader向follower节点复制数据成功后挂掉,客户端向新leader重发数据后会要求RPC 请求实现幂等性,也就是要实现内部去重机制。

若leader将数据成功复制到follower部分节点,但还未向leader响应接收这个阶段leader挂掉,数据在follower节点处于未提交状态且不一致,Raft 协议要求投票只能投给拥有最新数据的节点。所以拥有最新数据的节点会被选为leader再强制同步数据到follower,数据不会丢失并最终一致。

网络分区导致的脑裂情况,出现双leader。网络分区将原先的leader节点和follower节点分隔开follower收不到leader的心跳将发起选举产生新的leader。这时就产生了双leader,原先的leader独自在一个区,向它提交数据不可能复制到多数节点所以永远提交不成功。向新的leader提交数据可以提交成功,网络恢复后旧的leader发现集群中有更新任期(Term)的新leader则自动降级为follower并从新 leader处同步数据达成集群数据一致。

  • 服务发现框架

Consul基于Raft(CAP一致性算法)与Gossip(BASE最终一致性算法)进行实现的。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。

@client

CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。

@server

SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。

@server-leader

中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。

@raft

server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是taft。

@服务发现协议

consul采用http和dns协议,etcd只支持http

@服务注册

consul支持两种方式实现服务注册,一种是通过consul的服务注册http API,由服务自己调用API实现注册,另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。consul官方建议使用第二种方式。

@服务发现

consul支持两种方式实现服务发现,一种是通过http API来查询有哪些服务,另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。

@服务间的通信协议

Consul使用gossip协议管理成员关系、广播消息到整个集群,他有两个gossip  pool(LAN pool和WAN pool),LAN pool是同一个数据中心内部通信的,WAN pool是多个数据中心通信的,LAN pool有多个,WAN pool只有一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值