对于微服务的容错性设计,常见的有哪几种策略
对于微服务的容错性设计,常见的有以下四种策略:
1、隔离:
线程池隔离。线程池隔离就是通过Java的线程池进行隔离,B服务调用C服务给予固定的线程数量比如12个线程,如果此时C服务宕机了就算大量的请求过来,调用C服务的接口只会占用12个线程不会占用其他工作线程资源,因此B服务就不会出现级联故障。
信号量隔离。隔离信号量隔离是使用Semaphore来实现的,当拿不到信号量的时候直接拒接因此不会出现超时占用其他工作线程的情况。
2、熔断:
当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
3、降级:
降级是指当自身服务压力增大时,系统将某些不重要的业务或接口的功能降低,可以只提供部分功能,也可以完全停止所有不重要的功能。
4、限流:
限流,就是限制***流量。系统能提供的***并发有限,同时来的请求又太多,就需要限流。
漏桶算法。漏桶算法的思路,一个固定容量的漏桶,按照常量固定速率流出水滴。如果桶是空的,则不需流出水滴。可以以任意速率流入水滴到漏桶。如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
流量整形的流量整形的核心算法
流量整形的核心算法有以下两种,具体采用的技术为GTS(Generic Traffic Shaping),通用流量整形: 漏桶算法(Leaky Bucket)
漏桶算法是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。 令牌桶算法(Token Bucket)
有时人们将漏桶算法与令牌桶算法错误地混淆在一起。而实际上,这两种算法具有截然不同的特性并且为截然不同的目的而使用。它们之间最主要的差别在于:漏桶算法能够强行限制数据的传输速率,而令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。
在某些情况下,漏桶算法不能够有效地使用网络资源。因为漏桶的漏出速率是固定的参数,所以即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使某一个单独的流突发到端口速率。因此,漏桶算法对于存在突发特性的流量来说缺乏效率。而令牌桶算法则能够满足这些具有突发特性的流量。通常,漏桶算法与令牌桶算法可以结合起来为网络流量提供更大的控制。
Redis 限制频繁请求拦截处理
项目运维人员发现NGINX日志中短时间内有同一IP、同一用户、同一设备发出的大量请求,比用户正常行为产生的请求频率要高出很多,所以有对单位时间内访问频次限制的需求。
一般就会在服务器端将用户信息和访问信息做下关联,以此来实现访问频次限制。通常大家都会选择 Redis 来作为此中间件的存储介质。
几种最常用的限流算法:
固定窗口计数器算法概念如下:
固定窗口计数器是最为简单的算法,但这个算法有时会让通过请求量允许为限制的两倍。考虑如下情况:限制 1 秒内最多通过 5 个请求,在***个窗口的最后半秒内通过了 5 个请求,第二个窗口的前半秒内又通过了 5 个请求。这样看来就是在 1 秒内通过了 10 个请求。
滑动窗口计数器算法概念如下:
滑动窗口计数器是通过将窗口再细分,并且按照时间"滑动",这种算法避免了固定窗口计数器带来的双倍突发请求,但时间区间的精度越高,算法所需的空间容量就越大。
漏桶算法概念如下:
漏桶算法多使用 队列 实现,服务的请求会存到队列中,服务的提供方则按照固定的速率从队列中取出请求并执行,过多的请求则放在队列中排队或直接拒绝。
漏桶算法的缺陷也很明显,当短时间内有大量的突发请求时,即便此时服务器没有任何负载,每个请求也都得在队列中等待一段时间才能被响应。
令牌桶算法概念如下:
令牌桶算法既能够将所有的请求平均分布到时间区间内,又能接受服务器能够承受范围内的突发请求,因此是目前使用较为广泛的一种限流算法。
业务对此要求不高,所以用了简单的固定窗口计数器算法。
RateLimiter令牌桶算法浅析
百度百科中的定义:
令牌桶算法是网络流量(Traffic Shaping)整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。
大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的***令牌数永远不会超过桶的大小。
传送到令牌桶的数据包需要消耗令牌。不同大小的数据包,消耗的令牌数量不一样。令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以发送流量。令牌桶中的每一个令牌都代表一个字节。如果令牌桶中存在令牌,则允许发送流量;而如果令牌桶中不存在令牌,则不允许发送流量。因此,如果突发门限被合理地配置并且令牌桶中有足够的令牌,那么流量就可以以峰值速率发送。
令牌桶算法的基本过程:
假如用户配置的平均发送速率为r,则每隔1/r秒一个令牌被加入到桶中;桶最多可以存发b个令牌。如果令牌到达时令牌桶已满,则这个令牌会被丢弃;
当一个n个字节的数据包到达时,就从令牌桶中删除n个令牌,并且数据包被发送到网络;
如果令牌桶中少于n个令牌,则不会删除令牌,并且认为这个数据包在流量限制之外;
算法允许最长b个字节的突发,数据包的速率被限制成常量r。对于在流量限制外的数据包可以以不同的方式处理:
1)被丢弃;
2)放在队列中当令牌桶中累积了足够多的令牌时再传输;
3)继续发送,但需要做特殊标记,网络过载时将这些特殊标记的包丢弃。
令牌桶算法与漏桶算法(Leaky Bucket)的主要区别:
1)漏桶算法能够强行限制数据的传输速率,而令牌桶算法在能够限制数据的平均传输速率外,还允许某种程度的突发传输。
2)令牌桶算法中,只要令牌桶中存在令牌,就允许突发地传输数据直到达到用户配置的上限,它适合于具有突发特性的流量。
RateLimiter是Guava中开源的一个令牌桶算法工具类,可以轻松实现限流工作。
RateLimiter有两个实现类:SmoothBursty和SmoothWarmingUp;
两者区别:
1)都是令牌桶算法的变种实现
2)SmoothBursty加令牌的速度是恒定的,SmoothWarmingUp会有个预热期,在预热期内加令牌的速度是慢慢增加的,直到达到固定速度为止。其适用场景是,对于有的系统而言刚启动时能承受的QPS较小,需要预热一段时间后才能达到***状态。
测试示例:
示例1:创建一个令牌桶,每秒生成一个令牌,申请失败立即返回。使用CountdownLatch计数器模拟多线程并发,调用await()方法阻塞当前线程,当计数完成后,唤醒所有线程并发执行。
示例2:创建一个令牌桶,每秒生成0.1个令牌,即每10s才会有一个令牌,超时时间设置成20s,20s内获取不到令牌返回失败,20s内可以生成2个令牌,加上创建时桶里会有一个令牌,超时前最终会有3条线程拿到令牌,并且每个令牌获取时间相隔10s。使用CountdownLatch计数器模拟多线程并发:调用await()方法阻塞当前线程,当计数完成后,唤醒所有线程并发执行。
参考文档:
关于漏桶算法和漏桶算法数据结构的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。