面试题出发
怎么解决缓存出现雪崩?
- 更新策略在时间上做到比较均匀
- 热数据尽量分散到不同的机器上
- 多台机器主从复制或者多副本,实现高可用
- 实现熔断限流机制,对系统进行负载能力控制
发现前三者都是基本在机器数量上增加,最后则不同,是利用熔断限流机制,进行负载能力的控制。
限流实现方式有哪些
- 计数器方式
最简单的限流算法就是维护一个计数器 Counter,当一个请求来时,就做加一操作,当一个请求处理完后就做减一操作。如果这个 Counter 大于某个数了(我们设定的限流阈值),那么就开始拒绝请求以保护系统的负载了。
- 队列算法
队列流控是以队列的的方式来处理请求。如果处理过慢,那么就会导致队列满,而开始触发限流。这样的算法需要用队列长度来控制流量,在配置上比较难操作。如果队列过长,导致后端服务在队列没有满时就挂掉了。
-
漏斗算法
-
漏斗算法其实就是在队列请求中加上一个限流器,来让 Processor 以一个均匀的速度处理请求
-
令牌桶算法
-
从理论上来说,令牌桶的算法和漏斗算法不一样的是,漏斗算法中,处理请求是以一个常量和恒定的速度处理的,而令牌桶算法则是在流量小的时候“攒钱”,流量大的时候,可以快速处理。
- 基于相应时间的动态限流
这方面设计的典范是 TCP 协议的拥塞控制的算法。TCP 使用 RTT - Round Trip Time 来探测网络的延时和性能,从而设定相应的“滑动窗口”的大小,以让发送的速率和网络的性能相匹配。
- 基于相应时间的动态限流
Soul 上的解决方案
上面两道面试题都提到了熔断限流,那 Soul 上又是如何实现限流熔断机制的呢?
rateLimiter 插件
利用 Redis 令牌桶算法进行限流。和 Guava RateLimiter 的名字类似,但两者不一样。
Hystrix 插件
hystrix 插件是网关用来对流量进行熔断的核心实现。
使用信号量的方式来处理请求,基于 Netflix/Hystrix 来实现的。
Sentinel 插件
sentinel 为网关熔断限流提供能力。
resilience4j 插件
resilience4j 为网关熔断限流提供能力。
上述四个插件便是 Soul 上用于解决限流熔断机制。