主机屋wordpress建站,网络推广专员,机械设备网络推广方案,东莞公共资源交易中心官网目录
一、Sentinel 与 Gateway 的限流有什么差别#xff1f;
1.1、前置知识 - 四种常见的限流算法
1.1.1、Tips
1.1.2、计数器算法
1#xff09;固定窗口计数器算法
2#xff09;滑动窗口计数器算法
1.1.3、令牌桶算法
1.1.4、漏桶算法
1.2、解决问题 一、Sentinel…目录
一、Sentinel 与 Gateway 的限流有什么差别
1.1、前置知识 - 四种常见的限流算法
1.1.1、Tips
1.1.2、计数器算法
1固定窗口计数器算法
2滑动窗口计数器算法
1.1.3、令牌桶算法
1.1.4、漏桶算法
1.2、解决问题 一、Sentinel 与 Gateway 的限流有什么差别 1.1、前置知识 - 四种常见的限流算法
1.1.1、Tips
限流就是指对服务器请求量做限制避免因为突发的请求量过多导致服务器宕机.
比如我们的服务器只能抗住每秒 1000 的请求量但此时突然有 10000 的请求量来了那么就需要把你这么大的请求量拦下来按照服务能够承载的流量去放行起到一个流控的效果.
如何实现呢就来看看这主流的三种限流算法~ 1.1.2、计数器算法
计数器算法又包括两种算法如下
1固定窗口计数器算法
a首先他会将时间划分成多个窗口时间窗口也被称为 interval然后呢每一个窗口都会维护一个计数器一旦有一个请求在这个窗口出现计数器就会加一.
b随着这一时刻突然增多那么这个计数器就会越来越大所以限流就是在设置这个计数器的阈值数量超过阈值的请求就会被丢弃.
例如窗口大小是 1000ms阈值是3. 那么如果这 1000 ms 内的请求来了 4 个那么超过阈值的那一个请求就会被丢弃. 这种算法会有一点缺陷 例如窗口大小是 1000ms阈值是3. 我在 4000ms ~ 4500ms 之间一个请求都没有然后在 4500ms ~ 5000ms 之间来了三个请求你看这是没问题的吧...
接着在 5000ms ~ 5500ms 之间又来了三个请求并且 5500ms ~ 6000ms 之间也没有请求来那么这一看我这个窗口里也没超过呀.
但是仔细思考一下4500ms ~ 5500ms 之间不也是 1s 么等于说你这 1s 放行了 6 个请求如果你系统的最大 qps 是 3每秒最多处理 3 个岂不是就搞崩了.
如下图 那么为了解决上述问题就有了滑动窗口计数器算法~
2滑动窗口计数器算法
a滑动窗口计数算法中不光有窗口还会把窗口划分成更小的时区例如窗口大小是 1000ms分区比如是 2那么就会把 1s 按照两个区间来划分每个小的区间大小就是 500ms这个区间就是用来统计请求个数的
b真正的窗口呢我们还是按照 1s 来统计qps 的意义就是每秒请求量.
c窗口也是会移动的移动的方式由当前时间来决定窗口的范围就是用当前请求到达的时间 减 时间窗口interval之后的第一个时区算起.
例如时间窗口大小是 1000ms分区是 500msqps 是 3. 假设有三个请求分别是 900ms、 1250ms、1300 ms此时计算窗口大小就是 1300ms ~ 1300ms - 1000ms 的下一个时区也就是 500 ~ 1500ms一共有三个请求. 如果400ms 又来了一个请求是不是按照滑动窗口的计算方式就超出了因此就会抛弃掉.
但是如果按照固定窗口大小计算就有可能正好在 500 ~ 1500ms 这个区间也是一秒因此就会放行通过那这就相当于多放行了一个请求 那么滑动窗口就一定没问题么 不一定哦假设 1600ms 这个时候又来了一个请求就要出问题了乍一看窗口区间是 1600ms ~ 1600ms - 1000ms 的下一个时区也就是 1600ms ~ 1000ms只放行了三个请求.
但是仔细看一下1600ms 和 900ms 的这个请求之间差多少秒是不是 700ms也就是说这700ms 的时间连续放行了 4 个请求
因此滑动窗口知识解决了固定窗口的小问题而如果几个请求之在窗口之间挨的很近依然会出问题. 这个时候你就可以把这个时区再继续分的更细一点就能解决了. 例如 时区大小是 250ms那么窗口区间就是 1600ms ~ 750ms而此时一看窗口里面有 4 个请求就会把最后来的请求给抛弃了~
如下图 1.1.3、令牌桶算法
a令牌桶算法就说有一个桶这个桶里会以固定的速率去生成令牌这个速率实际上就是 qps.
b当这个桶满了以后就会把多余的令牌丢弃.
c每一个请求来的时候都会去申请一个令牌如果桶中没有令牌请求就会被丢弃.
例如qps 是5也就是生成 令牌的速率是每秒 5 个而此时桶中有 5 个令牌但是忽然有 6 个请求同时到来那么多出来的请求就会被丢掉. 令牌桶算法的缺陷 思考这样一个问题假设桶的容量是 5每秒生成 5 个令牌但非常神奇的是第一秒的时候一个请求都没有来而第二秒突然来了 10 个请求那么首先会先去桶里把存的 5 个令牌拿走这 5 个请求瞬间就过去了而第二秒的时候又要生成 5 个令牌剩下的 5 个令牌是不是也能过去.
这就超过阈值了... 他的缺陷同时也是一个好处 如果我们设置令牌的速度不是我们服务器的上限而是一个平均值偶尔超出也不会把服务压垮那么令牌桶就可以很好的处理突发的请求情况请求带有波动性的.
例如服务器的最大并发能力是 6我设置 qps 为 3令牌生成速度如果说第一秒没有请求来那么第二秒的时候来了 6 个请求此时就可以桶里有 6 个令牌就都能都放行处理了不会造成请求的丢失. 令牌桶的真正底层实现 虽然我们讲他是利用一个桶每秒钟生成多少令牌但是代码真正的实现可不是这样因为你还要弄个定时器去生成很麻烦.
令牌桶的代码实现思路是这样的
这个桶的话实际上里面并不会生成令牌而是记录上一个请求来的时间另外还记录了当前还有几个令牌了.只要记录了这两样东西那么当请求来了以后我只需要计算这个请求和上一个请求之间的时间差如果时间差在小于令牌在这段时间生成的数量就可以放行通过
例如我每秒生成 5 个令牌那么假设来了两个请求我就可以计算以下他两的时间差比如说是 0.2 秒那么当前的令牌个数就可以认为是 0.2 * 5 1因此此时只有一个令牌只能处理一个请求处理不了这第二个. 1.1.4、漏桶算法
a漏桶算法呢也有一个桶只不过不是用来存令牌的而是用来存请求的.
b当请求来了就会把它当成一滴水放到桶里面去然后漏桶就会以固定的速率向漏出请求.
c如果桶满了多余的请求就会被丢弃.
这就像是有一个桶但是桶下面开了一个小口当你往桶里倒水的时候水就会以固定的速率从这个固定大小的小口流出. 漏桶算法的优势 应对突发的请求假如漏桶的处理速度是每 3s 一个请求但是如果突发来了 10 个请求没关系我在桶里先存起来后面慢慢处理就可以.流量永远是平滑的不管你每秒是来了 10 个还是 100 个请求只要我桶够大那么放出去的速度永远都是固定的也就是说他处理请求的速度一直是一条直线.对比令牌桶对于令牌桶来说如果请求忽高忽低这个时候令牌桶就没办法保证平滑他有可能会出现忽高忽低的情况因为前一秒令牌没有用完可以累计在下一秒就有可能出现一次性被消耗完的情况. 漏桶算法的实现原理 a漏桶算法的请求实际上就是遵循先进先出那么用的容器肯定就是队列.
b当请求来的时候这些请求就会按照时间间隔依次执行.
c并且会有一个预期等待时间实际上就是桶的大小. 当新的请求到来时就会将桶中所有请求的等待时间加起来然后再加上新的请求如果大于预期等待时间这个新的请求就会被抛弃.
例如桶的预期等待时间是 2000ms桶的大小qps 是 5每秒通过 5 个请求也就相当于 200ms 处理一个请求.
突然某一时刻同时来了很多请求那么第一个请求进来时可以立即被执行因此等待时间就是 0ms第二请求就需要排队了就是 200ms 的时候会被执行往后以此类推. 当队列中所有请求的等待时间加起来等于 2000ms 的时候预期等待时间此时再来的请求就会被拒绝. 1.2、解决问题
明白上述的四种算法回答这个问题就游刃有余了~
这个时候你就可以说那么首先呢常见的有 3 种限流算法分别是 计数器算法、令牌桶算法、漏桶算法. Gateway 采用的是基于 Redis 实现的令牌桶算法key value 就是一个桶.
而 Sentinel 内部实现的比较复杂
默认限流模式是基于滑动时间窗口算法排队等待的限流模式则基于漏桶算法因为漏桶算法本身就是一种排队嘛请求来了如果前面还有请求没被执行就排队并且按照固定的频率去执行.而热点参数限流则是基于令牌桶算法热点参数的特点就是针对每个一个参数单独去统计那么你可以看作是一个接口比如查询商品将来商品的参数可能就是成千上万如果采用滑动窗口的方式那就需要进行时间分区并每个分区种都有一个计数器来统计那么对内存的消耗是非常大的. 如果使用令牌桶就只需要记住这个参数对应的令牌即可上一个请求来的时间.