注册中心八大功能解析
服务注册
服务续约
服务获取
服务调用
服务下线
失效剔除
自我保护
服务同步
技术选型 : nacos eureka consul zk
架构特性:CP AP AP 可用性非常强 极强可用 视频网站 在线直播 consul:深信服 奇安信 网宿 ZK:数据一致性要求高的场景 金融场景 金融供应链
Eureka:极强可用 多级缓存机制 多级缓存架构
Eureka心跳机制 30S 发送一次心跳 客户端发送到服务端 50个服务 40 = 2000个实例
2000乘以4乘以60乘以24 = 1152W 并发 稳定的请求
单机能够扛住大量的请求
Nacos的Raft一致性算法
Raft算法
在学术界中分布式一致性算法的基石还是Paxos为代表,Paxos算法是Lamport宗师提出的一种基于消息传递的分布式一致性算法,使其获得2013年图灵奖。
由于Paxos难以理解,而且很难落地到工程实践,所以Paxos在工程中运用的并不多
取而代之的是易理解易实现的Raft算法,号称几乎等同于Paxos,但是性能肯定不及Paxos
分布式一致性算法也称为共识算法,是指在大型分布式系统中,在遇到请求时,各个节点的数据能够保持一致,并且在遇到部分机器宕机时,也能保证整体服务的数据一致性
学习Raft算法最好的方式则是阅读论文:https://raft.github.io/raft.pdf
关于Raft协议步骤动画:http://thesecretlivesofdata.com/raft/
(这两个网站目前都挂了,反正我访问不到了)
这里我们了解Raft算法中核心逻辑,Raft算法中其实大致分为三个子问题
Leader Election 、Log Replication、Safety,对应的也就是选主,日志复制,安全性(通过安全性原则来处理一些特殊 case,保证 Raft 算法的完备性)
Raft的核心流程归纳:
首先选出 leader,leader 节点负责接收外部的数据更新/删除请求
然后日志复制到其他 follower节点,同时通过安全性的准则来保证整个日志复制的一致性
如果遇到 leader 故障,followers 会重新发起选举出新的 leader
Raft节点有三种状态:
Leader(领导者)
Follower(跟随者)
Candidate(候选人)
Leader Election 领导选举
所有节点一开始都是follower状态,一定时间未收到leader的心跳,则进入candidate(候选人)状态,参与选举.选出leader后,leader通过向follower发送心跳来表明存活状态,若leader故障,则整体退回到重新选举状态
每次选举完成后,会产生一个term,term本身是递增的,充当了逻辑时钟的作用
具体的选举过程:领导者与跟随者建立心跳(心跳时间随机,为了避免大多数跟随者在同一时间进行选举)并等待,若超时未等到,准备选举 —-> current term ++,转变为candidate(候选人)状态 —-> 给自己投票,然后给其他节点发送投票请求 —-> 等待选举结果
具体投票过程有三个约束:
在同一任期内,单个节点最多只能投一票
候选人知道的信息不能比自己的少(Log与term)
first-come-first-served 先来先得
选举结果有三种情况:
收到大部分(超过半数)的投票(含自己的一票),则赢得选举,成为leader
被告知别人已当选,那么自行切换到follower
一段时间内没有收到超过半数以上的投票,则保持candidate状态,重新发出选举。(ps:如果是遇到平票现象,则会增加系统不可用时间,因此,raft中引入了randomized election timeouts,尽量避免出现平票现象的产生)一旦选举完毕,leader节点会给所有其他节点发消息,避免其他节点触发新的选举
配置中心几种配置推送方式以及nacos的推送方式
1、动态监听
- Push表示服务端主动将数据变更信息推送给客户端
1 | 推送的模式服务器必须保持客户端的长连接,这样服务端会耗费大量的内存,并且还要检测链接的有效性。需要一些心跳机制来维护 |
- Pull表示客户端主动去服务端拉取数据
1 | 这样客户端缺少了时效性,客户端不可能实时的从服务端拉取的,他要有时间间隔的。这个时间间隔不好控制,时间长了就实时性不高,时间短了,如果配置没有变化时候他会有需要无效的拉取。 |
2、动态刷新流程图(长轮询机制)
客户端会轮询向服务端发出一个长连接请求,这个长连接最多30s就会超时,服务端收到客户端的请求会先判断当前是否有配置更新,有则立即返回如果没有服务端会将这个请求拿住“hold”29.5s加入队列,最后0.5s再检测配置文件无论有没有更新都进行正常返回,但等待的29.5s期间有配置更新可以提前结束并返回。
Nacos服务端采用长轮询机制相比传统的短轮询或简单的长连接具有多个显著的好处。以下是对这些好处的详细归纳:
1. 降低推送延迟
- 减少延迟时间:在短轮询中,客户端需要定期(如每5秒)向服务端发送请求以检查配置是否更新,这可能导致较大的延迟。如果配置变更发生在两次轮询之间,客户端需要等待直到下一次轮询才能获取到更新。而长轮询机制下,客户端发起请求后,服务端会hold住该请求,直到配置发生变化或达到超时时间才返回结果,从而显著降低了推送延迟。
2. 减轻服务端压力
- 减少无效请求:在传统的轮询机制中,无论配置是否发生变化,客户端都会定期发送请求,这会对服务端造成不必要的压力。而在长轮询中,当配置未发生变化时,服务端会挂起客户端的请求,不会立即返回响应,从而减少了无效请求的数量,减轻了服务端的压力。
- 资源利用更高效:由于长轮询减少了无效请求,服务端的资源(如CPU、内存、数据库连接等)可以得到更有效的利用,提高了整体的资源利用率。
3. 实现更高效的配置推送
- 实时性更强:长轮询机制使得配置变更能够更实时地推送到客户端。一旦配置发生变化,服务端会立即将更新推送给所有等待的客户端,而无需等待下一次轮询周期。
- 减少客户端资源消耗:客户端无需频繁地发送请求以检查配置是否更新,从而减少了网络带宽和CPU资源的消耗。
4. 更好的用户体验
- 减少等待时间:由于推送延迟的降低,用户在访问依赖于配置的服务时能够更快地看到更新后的内容,从而提升了用户体验。
- 更稳定的服务:长轮询机制有助于保持服务的稳定性,减少了因配置未及时更新而导致的服务异常或错误。
5. 易于实现和维护
- 代码简洁:长轮询机制的实现相对简单,通常只需要在服务端维护一个等待队列和相应的超时机制即可。
- 易于扩展:随着业务的增长和配置项的增多,长轮询机制可以很容易地进行扩展以支持更多的客户端和更复杂的配置场景。
综上所述,Nacos服务端采用长轮询机制具有降低推送延迟、减轻服务端压力、实现更高效的配置推送、提升用户体验以及易于实现和维护等多个好处。这些好处使得Nacos成为了一个高效、可靠且易于扩展的配置中心解决方案。
在微服务中有几种限流方式
令牌桶
令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。
令牌桶是一个存放固定容量令牌(token)的桶,按照固定速率往桶里添加令牌; 令牌桶算法实际上由三部分组成:两个流和一个桶,分别是令牌流、数据流和令牌桶
令牌流与令牌桶
系统会以一定的速度生成令牌,并将其放置到令牌桶中,可以将令牌桶想象成一个缓冲区(可以用队列这种数据结构来实现),当缓冲区填满的时候,新生成的令牌会被扔掉。这里有两个变量很重要:
第一个是生成令牌的速度,一般称为 rate 。比如,我们设定 rate = 2 ,即每秒钟生成 2 个令牌,也就是每 1/2 秒生成一个令牌;
第二个是令牌桶的大小,一般称为 burst 。比如,我们设定 burst = 10 ,即令牌桶最大只能容纳 10 个令牌。
数据流
数据流是真正的进入系统的流量,对于http接口来说,如果平均每秒钟会调用2次,则认为速率为 2次/s。
漏桶
漏桶算法思路是,不断的往桶里面注水,无论注水的速度是大还是小,水都是按固定的速率往外漏水;如果桶满了,水会溢出;
桶本身具有一个恒定的速率往下漏水,而上方时快时慢的会有水进入桶内。当桶还未满时,上方的水可以加入。一旦水满,上方的水就无法加入。桶满正是算法中的一个关键的触发条件(即流量异常判断成立的条件)。而此条件下如何处理上方流下来的水,有两种方式
在桶满水之后,常见的两种处理方式为:
1)暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水。
2)溢出的上方水直接抛弃。
特点
漏水的速率是固定的
即使存在注水burst(突然注水量变大)的情况,漏水的速率也是固定的
计数器
这个最简单,比如用Redis做计数器
计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。此算法在单机还是分布式环境下实现都非常简单,使用redis的incr原子自增性和线程安全即可轻松实现。
滑动窗口
滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。
简单解释下,发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接受方确定,目的在于控制发送速度,以免接受方的缓存不够大,而导致溢出,同时控制流量也可以避免网络拥塞。下面图中的4,5,6号数据帧已经被发送出去,但是未收到关联的ACK,7,8,9帧则是等待发送。可以看出发送端的窗口大小为6,这是由接受端告知的。此时如果发送端收到4号ACK,则窗口的左边缘向右收缩,窗口的右边缘则向右扩展,此时窗口就向前“滑动了”,即数据帧10也可以被发送。
参考如下网址提供的动态效果
raft一致性算法演示
情况1:
问题:假设现在有S1,S2,S3,S4,S5,五个节点,领导者S5接受了一个add请求,现在自己日志add了,然后发送信息让其他节点S1,S2,S3,S4,也add到日志了。这个时候领导者S5宕机了,也就是说接收不到其他节点的成功返回信息了,不能进行commit操作,怎能办?这个add操作还有效吗?
解答:add操作有效。
题目情况时,S5宕机,其他节点重现选举,选出新的任期领导者,新的领导者收到新的add信息,准备提交时,同时也将原S5任期添加的信息一块提交了。
如下:
S5宕机,此时,各个节点已经更新任期2日志条目,此时没有提交(commit)。
S5宕机后,其他节点重新选举。新领导者S2,任期3。节点3更新提交条目的时候,原任期2的日志条目也被提交了。
S5重启,S5角色是跟随者,任期为3,原来任期2,现在任期3的日志会被同步。和领导者保持一致。
情况2:
问题:假设现在有S1,S2,S3,S4,S5,五个节点,领导者S5接受了一个add请求,现在自己日志add了,然后发送信息让节点S1,S2,S3,进行更新日志,还没对 S4发送,这个时候领导者S5挂了怎能办?如果这时候还是S4先到了过期时间,S4向S1,S2,S3,发送了投票请求会发生什么?
解答:S5挂掉,S4超时 时,S4请求投票,但S1,S2,S3拒绝投票。(原因:S1,2,3,检测S4完整度没自己高,比较index)。继续进行下一次选举。
S5挂掉,S4超时 时:
S4被拒绝投票后,重新选举结果,S3当选领导者。如下图:
S3再收到客户端请求,会更新最新日志,任期2的日志也同时会被提交。
情况3:
问题:假设现在有S1,S2,S3,S4,S5,五个节点,领导者S2接受了一个请求,让S4更新了,还没让S1,S3,S5更新就宕机了,这个时候还是S3先TIMEOUT了,会发生什么?这个和情况2有什么不同?
解答:S2宕机,S4更新,S3timeout时,S3发起投票,S4会因为index比S3大拒绝,但S1,S2,多数会接受,同意。S3当选领导者。S3添加日志,会覆盖S4日志(按照领导者的index来维护日志Index)。
情况2,S1,S2,S3,是已经存在有日志更新了,占据了绝大多数,另一个不会被选上。选上的是S1,S2,S3,其中之一,包含已经存在的日志,不会被覆盖。
S2宕机,S4更新:
S3timeout时,S3发起投票:
S3日志覆盖S2,S4日志。