网关限流的方式一般有令牌桶算法和漏桶算法。
令牌桶算法
令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:
假如用户配置的平均速率为r,则每隔1/r秒一个令牌被加入到桶中;
假设桶最多可以存放b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃;
当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上;
如果令牌桶中少于n个令牌,那么不会删除令牌,并且认为这个数据包在流量限制之外;
算法允许最长b个字节的突发,但从长期运行结果看,数据包的速率被限制成常量r。
对于在流量限制外的数据包可以以不同的方式处理:
(1)他们可以被丢弃
(2)他们可以排放在队列中以便当令牌桶中积累了足够多的令牌时再传输
(3)他们可以继续发送,但需要做特殊标记,网络过载的时候将这些特殊标记的包丢弃
漏桶算法
漏桶作为计量工具时,可以用于流量整形和流量控制,漏桶算法的描述如下:
一个固定容量的漏桶,按照常量固定速率流出水滴;
如果桶是空的,则不需要流出水滴;
可以以任意速率流入水滴到漏桶;
如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
Spring cloud gateway默认的限流
spring cloud gateway默认的限流是基于redis的令牌桶算法实现,
基于 Stripe的redis实现方案,依赖spring-boot-starter-data-redis-reactiveSpring Boot starter,使用的是令牌桶算法。
redis-rate-limiter.replenishRate配置的是每秒允许通过的请求数,其实就是令牌桶的填充速率。
redis-rate-limiter.burstCapacity配置的是一秒内最大的请求数,其实就是令牌桶的最大容量,如果设置为0,则会阻塞所有请求。