首页 > 编程知识 正文

服务限流算法,三大运营商提速降费

时间:2023-05-03 06:19:41 阅读:23891 作者:4576

文章目录10分钟了解系列服务限流计数器法滑动窗口法漏桶算法令牌桶算法服务降级

10分钟了解序列号标题链接110分钟企业服务总线https://blog.csdn.net/belongtocode/article/details/11948731210分钟微内核体系结构https://119107837310分钟全面了解服务限制和服务降级3359 blog.csdn.net/belongtocode/article/details/119107785410分钟负载平衡https://blog 118977839510分钟使用集群容错和服务隔离https://blog.csdn.net/belongtocode/article/details/11896871610分钟使用注册中心https://blog . 118639474710分钟了解RPC体系结构https://blog.csdn.net/belongtocode/article/details/118639448

我们知道,在分布式系统中,面对高并发、大流量的APP应用场景时,系统有崩溃的风险。 此时,为了提高系统的可用性,需要限制外部通信量以减少对现有系统的影响。 目前业界主流的两个最佳做法是服务限制和服务降级。 在本课中,您将详细介绍这两个解决方案。

如果您正在设计和开发分布式服务系统,则每个服务通常会相互依赖形成复杂的调用链接,以满足特定的业务需求。 那么,在这样的调用链接中,如下所述,服务自身可能无法承受大量的请求而调用失败,或者由于该服务所依赖的其他服务存在问题而自身失败。

应对这两个失败场景有两个核心的解决思路。 如果服务本身发生了失败,我们希望通过合理控制对其的要求量来降低失败的可能性。 这是服务限制方案。 如果依赖服务出现问题且调用失败,则希望另一个服务在访问该服务时快速返回错误,以防止服务依赖导致的“雪崩效应”(即服务降级)。

下面,我们先来详细了解一下下限流程的具体实现。

迷路进入服务限制流的信封,限制流意味着限制访问服务的业务,避免高业务,特别是突发性高业务破坏服务。 服务器希望通过受限的流,能够基于自己的可控速度消耗外部请求,如下图所示。

为了实现这一目标,业内也有一些已被证明是通用且实践可行的方法,包括用于流控制的计数器法和滑动窗口法,以及用于流整形的漏桶算法和令牌桶算法。

基于计数器法业务计数器的流限制算法的基本思想非常简单,是控制一定时间内的请求数,如果该请求数在适当的访问阈值内,就被认为有流限制的效果。 具体实现方法是设置计数器,记录并统计所有来自外部的要求量。

举个例子吧。 假设计数器阈值为10,则在单位时间内来自系统的累计请求量超过10的情况下,可以直接拒绝超过部分。 的执行效果如下。

当然,这种做法需要在一个单位时间结束时,清除计数器累积的要求量。

计数器算法可以说是限流算法中最简单最容易实现的算法,但也存在着临界问题这一必须面对的问题。 这是什么意思呢?

想象一下。 将单位时间设定为10秒,阈值也设定为10。 假设现在服务请求在第10秒结束时一次发送了6个请求。 此时,一个单位时间结束,计数器被清除。 在第11秒开始的瞬间,原则上可以发送8个请求。 如此短的时间内,服务a就会收到6 8=14的请求,如果超过流限制阈值,服务可能会失败。 整个过程如下图所示。

滑动法面对这种情况,我们该怎么办?

答案可以使用滑动窗口机制进行电流限制。 滑动窗口可使基于时间段的统计信息更加平滑。 本质上,划分一个单位时间,形成多个时间段。

例如,可以将10秒的单位时间分为10个时间框架,每个框架表示1秒。 每一秒,时间窗口向前滑动一个小时。

此时,请注意每个时间框架都有独立的计数器。 滑动窗口可以解决临界问题的关键就在这里。 假设在第一个时间边界点,即第10秒,前后分别有6个和8个请求到达系统,则在第10秒结束时,当前窗口向前滑动1小时,因此此时窗口内的请求数为6 8=14个。

从这个角度看,滑动窗口也是计数算法,但是可以将单位时间设置得更细,更好地适应业务的突然变化。

泄漏桶算法在描述了流量限制的常用方法之后,我们来看看流量整形的两种实现方法。

我们先来看看漏桶算法。 漏斗应该很清楚。 其基本特征是

就是进口大、出口小,不管我们以怎样的速度往漏斗里倒入液体,但这些液体从出口流出的速率总是一样的。

这样,我们就可以把服务调用量看作是液体,那么不管服务请求的变化多么剧烈,通过漏桶算法进行整形之后,得到的就是具有固定速度的请求量:

从这张图中,我们能看到请求 1~9 以不同的速率进入漏桶,而输出的则是固定速率的请求 1~5,剩余的请求会继续留在漏桶。

这里你要注意,漏桶本身的容量肯定也不是无限大的,所以当请求数量超过了桶的容量,新来的请求也只能被丢弃掉了。

令牌桶算法

讲到这里,实际上我们也可以看出漏桶算法的一个缺点,因为漏桶的容量是有限的,而输出的速率又是固定的,所以当面对突发的请求流量时,我们无法有效应对流量的变化。这时候,使用令牌桶算法则是更为合适的一种选择。

令牌桶算法的结构如下图所示:

令牌桶算法的具体实现是这样的:我们以固定的速度将令牌放入桶中,一个令牌对应一个请求。如果在某一时间点上,桶中已经没有令牌了,那么请求就不会得到响应,而如果桶中存放着很多令牌,就可以响应很多的请求,因此服务请求的输入和输出都可以是变速的。

由此可见,和漏桶算法不一样的是,令牌桶算法应对突发流量的解决方法是允许出现动态的输出速率。

以上就是服务限流方案的实现原理,接下来我们来看看服务降级的策略。

服务降级

所谓服务降级,指的是在服务器压力剧增的情况下,根据当前业务情况及流量对一些服务执行有策略的快速失败处理,以避免服务之间的调用依赖影响到其他核心服务:

具体要如何实现服务降级呢?

业界的主流做法就是进行服务熔断。服务熔断的原理和电路熔断很像,我们知道在电路系统中一般都会设计一个熔断器(Circuit Breaker),确保当电流过大时能够自动切断电路。而在分布式系统中,熔断的含义就是当某一个服务已经无法正常响应请求时,其他服务就不再继续向它发起请求,以确保调用链路不会发生雪崩效应。

从设计理念上讲,当服务消费者向服务提供者发起远程调用时,服务熔断器就会监控这次调用,如果调用的响应时间过长,那么熔断器就会中断本次调用并直接返回。请注意,熔断器判断本次调用是否应该快速失败是有状态的,也就是说熔断器会把所有的调用结果都记录下来,只有发生异常的调用次数达到一定阈值,才会触发熔断机制,而不是一有异常就直接进行熔断。

因此,既然熔断器内部是有状态的,那我们就可以对这些状态进行抽象和提炼,从而得到如下所示的状态转换图:

这个状态转换的具体过程是这样的:

首先,如电路系统一样,在默认情况下熔断器都是关闭的,任何请求都会得到响应。系统会记录所有的请求处理结果,并会统计失败的调用次数,看是否已经达到了规定的熔断阈值。

然后,一旦失败调用次数到达阈值,熔断器就会打开。对于任何请求而言,都将得到失败的响应结果。请注意,这时候系统的请求处理过程是不会真正执行远程调用的,而是会执行快速失败策略。而一旦发生熔断,熔断器内部会启动一个时钟,一段时间之后就会自动进入半熔断状态。

处于半熔断状态的熔断器会允许一部分请求真正得到响应,同时也会统计调用成功的次数。如果成功的次数到达一定的数量,我们就认为系统已经恢复正常,熔断器就会关闭。而如果请求还是会不断发生错误,那么熔断器又会被重新打开。

好,以上就是这节课的主要内容。在日常开发过程中,我们可以使用服务限流和降级机制为分布系统提升服务访问的可靠性。

最后,我想给你留一道思考题:你能描述熔断器应该具备的三个状态以及它们之间的转换过程吗?你可以在评论区留下你的答案,和我讨论。

参考文章:
整理于极客时间每日一课对应文章

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。