2预估系统流量上限
采用压测方法。对某个接口进行压测,逐步调高并发量和持续时间,达到系统瓶颈时(错误率高,响应时间长)记录下并发量,这个值就是当前系统流量上限。
3限流方案
3.1系统维度
从系统维度来看可以分为单机限流和集群限流两种方式。
单机限流是对每一台机器限流,假设每台机器限流100QPS,集群有10台机器,那么整个集群有1000QPS能力。可以使用GuavaRateLimiter、Java并发包Semaphore实现单机限流。
集群限流是对整个集群进行限流,比如预估整个集群能力有1000QPS,还有一种场景是限次,比如整个集群只能调用第三方接口多少次。可以使用Redis实现全局限流。
3.2方法维度
限流常用方法有以下三种:
计数器法
维护一个计数器,这个计数器有一个时间窗口,在当前时间窗口,每当一个新请求到来时,计数器自增,当计数器自增达到设置的上限时,不再提供服务。滑动到下一个时间窗口时,计数器重置。这种方法的特点是简单,但是在时间窗口临界点,可能会出现超出流量的问题。
漏桶算法
漏桶算法强制一个常量的输出速率而不管输入数据流的突发性。当输入空闲时,该算法不执行任何动作,就像用一个底部开了个洞的漏桶接水一样,水进入到漏桶里,桶里的水通过下面的孔以固定的速率流出。当水流入速度过大会直接溢出。
令牌桶算法
偶推荐这种方法。一个容量固定的桶,以一个恒定的速率产生令牌,如果桶内的令牌满了则多余的令牌会被丢弃。每当请求进来时,先去桶内拿一个令牌,桶内的令牌拿完了,则必须等待桶内产生令牌才能允许后续的请求(或者直接拒绝)。由于桶内可以堆积一定的令牌(一般为桶容量),所以令牌桶算法优点是可以允许一定量的流量高峰。
Guava提供了限流工具RateLimiter基于令牌桶完成限流。也可以通过编写Lua脚本通过Redis实现全局令牌桶。