3. 限流模式数组
服务的容量和性能是有限的,在第3章中会介绍如何在架构设计过程当中评估服务的最大性能和容量,然而,即便咱们在设计阶段考虑到了性能压力的问题,并从设计和部署上解决了这些问题,可是业务量是随着时间的推移而增加的,忽然上量对于一个飞速发展的平台来讲是很常见的事情。架构
针对服务忽然上量,咱们必须有限流机制,限流机制通常会控制访问的并发量,例如每秒容许处理的并发用户数及查询量、请求量等。并发
有以下几种主流的方法实现限流。微服务
1)计数器性能
经过原子变量计算单位时间内的访问次数,若是超出某个阈值,则拒绝后续的请求,等到下一个单位时间再从新计数。.net
在计数器的实现方法中一般定义了一个循环数组(见下图),例如:定义5个元素的环形数组,计数周期为1s,能够记录4s内的访问量,其中有1个元素为当前时间点的标志,一般来讲每秒程序都会将前面3s的访问量打印到日志,供统计分析。线程
咱们将时间的秒数除以数组元素的个数5,而后取模,映射到环形数组里的数据元素,假如当前时间是1 000 000 002s,那么对应当前时间的环形数组里的第3个元素,下标为2。架构设计
此时的数组元素的数据以下图所示。设计
在上图中,当前时间为1 000 000 002s,对应的计数器在第3个元素,下标为2,当前请求是在这个时间周期内的第1个访问请求,程序首先须要对后一个元素即第4个元素,也就是下标为3的元素清零;在1 000 000 002s内,任何一个请求若是发现下标为3的元素不为0,则都会将原子变量3清零,并记录清零的时间。日志
这时程序能够对第3个元素即下标为2的元素,进行累加并判断是否达到阈值,若是达到阈值,则拒绝请求,不然请求经过;同时,打印本次及以前3秒的数据访问量,打印结果以下。
当前:1次,前1s:302次,前2s:201次,前3s:518次
然而,若是当前秒一直没有请求量,下一秒的计数器始终不能清零,则下一秒的请求到达后要首先清零再使用,并更新清零时间。
在下一秒的请求到达后,若检查到当前秒对应的原子变量计数器不为0,并且最后的清零时间不是上一秒,则先对当前秒的计数器清零,再进行累加操做,这避免发生上一秒无请求的场景,或者上一秒的请求因为线程调度延迟而没有清零下一秒的场景,后面这种场景发生的几率较小。
另一种实现计数器的简单方法是单独启动一个线程,每隔必定的时间间隔执行对下一秒的原子变量计数器清零操做,这个时间间隔必须小于计数时间间隔。
2)令牌筒
令牌筒是一个流行的实现限流的技术方案,它经过一个线程在单位时间内生产固定数量的令牌,而后把令牌放入队列,每次请求调用须要从桶中拿取一个令牌,拿到令牌后才有资格执行请求调用,不然只能等待拿到令牌再执行,或者直接丢弃。
令牌筒的结构以下图所示。
3)信号量
限流相似于生活中的漏洞,不管倒入多少油,下面有漏管的流量是有限的,实际上咱们在应用层使用的信号量也能够实现限流。
4. 失效转移模式
若微服务架构中发生了熔断和限流,则该如何处理被拒绝的请求呢?解决这个问题的模式叫做失效转移模式,一般分为下面几种。
转载博客:https://blog.csdn.net/kwame211/article/details/78015601