开发必备:接口的限流思想总结

前言

在编写一个web服务时,我们需要提供接口来来与用户进行交互。那么,无论是出于资源有限还是防止单用户无限请求占用CPU资源,导致服务不可用造成严重后果,对某些重要的接口做限流是非常必要的。

知识点速览

  • 什么是限流?
  • 限流的粒度?
  • 四种经典限流算法:思想固定窗口、滑动窗口、漏桶、令牌桶算法
  • 单机限流与多机限流?(单体项目下与分布式项目下) 一些库的实现例如Gava、Redission

什么是限流?

主要是系统为了面对突发的流量处理不过来时,丢弃一些请求来确保服务的持续可用所做的措施。

限流的粒度

  • 针对某个有限服务,只允许被其他服务/每个用户调用N次。
  • 针对某个接口,只允许在同一时间被调用N次。
  • 针对用户的可调用的某个方法,只允许某个用户在某个时间段内调用N次。例如发送短信接口

四种经典限流算法的思想

固定窗口算法

在某个时间间隔内,通过多少请求。

例如:- 1s的间隔内允许5个请求通过

固定窗口算法优缺点

优点

最简单,我们可以只利用一个count计数器,以及startTime、与endTime来做更新。

缺点

可能出现流量突刺

比如:第一个1s间隔内,前0.6s无任何操作,后0.4s秒来了5个请求,而在第二个间隔内,前0.6s来了5个请求,那么在这1s内,就有10个请求,此时是不是不符合限流策略?

滑动窗口算法

单位时间内允许部分操作,但是单位时间是滑动的,需要指定一个滑动单位(例如4s),如下图所示

它的机制是从当前时间的前一个阈值算起,比如说现在是4s,阈值是4s,那么如果在0s - 4s 内的请求超出了预期值,那么此时的请求将会被丢弃。

滑动窗口算法优缺点

优点

滑动窗口算法可以解决固定窗口存在的流量突刺问题,平滑的处理请求。只要是在当前时间-阈值时间当前时间内,达到阈值时,更多的操作就会被拒绝。

缺点

实现起来比较复杂,限流的效果和你的滑动单位 有关,滑动的单位越小,限流的效果就会越好,但是实际上我们往往很难选取到一个特别合适的滑动单位,一般都需要结合业务需求

漏桶算法

该算法以固定的速率去处理请求,当请求打满了桶之后后,拒绝请求。 每秒处理10个请求,桶的容量是10,每0.1秒固定处理一次请求,如果1s内来了10个请求,都可以处理完,但如果1秒内来了11个请求,最后那个请求就会溢出桶,被拒绝

漏桶算法优缺点

优点

能够一定程度上应对流量突刺,固定速率处理请求,保证服务器的安全

缺点

没有办法迅速处理一批请求,只能一个一个按顺序来处理(固定速率的缺点)

令牌桶算法

系统先生成一批令牌,例如每秒生成10个令牌,当用户要操作前,先去拿到一个令牌,有令牌的人就有资格、能同时执行操作。拿不到令牌就阻塞

令牌桶算法的优缺点

优点

能够并发处理同时的请求,并发性能会更高。只要令牌够,在0.1s内处理10个请求都行。

缺点

最大的问题是:时间单位选取很重要。在0.1s内虽然处理了10个请求,不过后续的0.9s的请求都将失败。

限流的实现

限流的实现我们可以直接调用一些函数库

单机限流(本地限流)

可以使用Gava的RateLimite

java 复制代码
import com.goole.common.util.concurrent.RateLimiter;
public static void main(String[] args){
	RateLimiter limiter = RateLimiter.create(5.0);
	while(true){
		if(limiter.tryAcquire()){
			//处理请求
		}else{
			//超过流量限制,需要的处理方式
		}
	}
}

多机限流

  • 把项目用户的使用频率等数据放到一个集中的存储进行统计,比如Redis,这样无论用户请求落到哪台服务器,都以集中的数据存储内的数据为标准 (Redisson)
  • 在网关集中进行限流和统计(比如Sentinel、Spring Cloud Gateway)
java 复制代码
import org.redisson.Redisson;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;

public static void main(String[] args){
	//创建RedissonClient 
	RedissonClient redisson = Redisson.create();
	//获取限流器
	RSemaphore semaphore = redisson.getSemaphore("mySemaphore");
	//尝试获取许可证
	boolean result = semaphore.tryAcquire();
	if(result){
		//处理请求
	}else{
		//超出流量限制,需要做的处理
	}
}

总结

本文介绍了四种经典限流算法,效果较好的是滑动窗口与令牌桶算法。都可以比较好的应对流量突刺问题以及处理效率问题。固定窗口算法最大的缺点是无法处理流量突刺,而漏桶算法则是只能以恒定的速率处理请求。而在实际开发中,我们一定要遵循业务需求,先理解业务再去选择合适的实现方案。

相关推荐
Yuan_o_34 分钟前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
程序员一诺1 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
快乐非自愿1 小时前
分布式系统架构2:服务发现
架构·服务发现
2401_854391081 小时前
SSM 架构中 JAVA 网络直播带货查询系统设计与 JSP 有效实现方法
java·开发语言·架构
264玫瑰资源库1 小时前
从零开始C++棋牌游戏开发之第二篇:初识 C++ 游戏开发的基本架构
开发语言·c++·架构
神一样的老师1 小时前
面向高精度网络的时间同步安全管理架构
网络·安全·架构
2401_857026231 小时前
基于 SSM 架构的 JAVA 网络直播带货查询系统设计与 JSP 实践成果
java·开发语言·架构
9527华安2 小时前
FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持
fpga开发·架构·mipi·imx327·fpd-link·fpd953
thatway19892 小时前
AI-SoC入门:15NPU介绍
后端
陶庵看雪2 小时前
Spring Boot注解总结大全【案例详解,一眼秒懂】
java·spring boot·后端