为什么要进行网关限流?
在前面我们介绍的游戏服务端架构中,客户端通过Socket连接直连网关,所有请求都需要经过网关,然后由网关统一进行转发,为了避免玩家的DDOS攻击,所以需要在网关进行限流。
常见的算法主要有计数器限流、令牌桶限流和漏桶限流,这些算法都是单机的算法,正好可以用在网关限流。
算法
1、计数器限流
严格意义上来说计数器限流不属于限流算法,使用计数器来进行限流,主要用来限制总并发数,比如数据库连接数;只要全局总请求数或者一定时间段的总请求数设定的阀值则进行限流,是简单粗暴的总数量限流,而不是平均速率限流。
2、令牌桶算法(Token Bucket)
令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:
假设限制1秒钟生成2个令牌,则按照500毫秒的固定速率往桶中添加令牌;
桶中最多存放a个令牌,当桶满时,新添加的令牌被丢弃或拒绝;
当有n个请求到达,将从桶中删除n个令牌,接着请求被发送到网络上;
如果桶中的令牌不足n个,则不会删除令牌,该请求将被限流(要么丢弃,要么缓冲区等待)。
3、漏桶算法(Leaky Bucket)
漏桶算法是一个存放固定水滴的桶,按照固定速率流出水滴,可以用于流量整形和流量控制,漏桶算法的描述如下:
一个固定容量的漏桶,按照常量固定速率流出水滴;
如果桶是空的,则不需流出水滴;
可以以任意速率流入水滴到漏桶;
如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃,要么缓冲区等待),而漏桶容量是不变的。
对比
令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;漏桶是按照固定速率从桶中流出请求,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝
令牌桶限制的是平均流入速率,允许突发请求,只要有令牌就可以处理,支持一次拿5个令牌,6个令牌,并允许一定程度突发流量;漏桶限制的是常量流出速率,即流出速率是一个固定常量值,比如都是2的速率流出,而不能一次是2,下次又是3,从而平滑突发流入速率
基于Golang的算法实现:https://github.com/MaxwellBackend/Games/tree/master/ratelimit
有疑问加站长微信联系(非本文作者)