一.什么是限流
在频繁的网络请求时,服务有时候会受到很大的压力,尤其是那种网络攻击,非法的。这样的情形有时候需要作一些限制。限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。例如:限制对方的请求,这种限制可以有几个依据:请求IP、用户唯一标识、请求的接口地址等等。
二.为什么要进行限流
互联网系统通常都要面对大并发大流量的请求,在突发情况下(最常见的场景就是秒杀、抢购),瞬时大流量会直接将系统打垮,无法对外提供服务。那为了防止出现这种情况最常见的解决方案之一就是限流,当请求达到一定的并发数或速率,就进行等待、排队、降级、拒绝服务等。
例如:12306购票系统,在面对高并发的情况下,就是采用了限流。在流量高峰期间经常会出现提示语;“当前排队人数较多,请稍后再试!”
三.常见限流算法
1.计数器法
设置一个时间窗口内允许的最大请求量,如果当前窗口请求数超过这个设定数量,则拒绝该窗口内之后的请求。
重点是①时间窗口②计数器。
举个例子,我们设置1秒钟的最大请求数量为100,使用一个计数器来记录这一秒中的请求数。每一秒开始时,计数器都从0开始记录请求量,如果在这一秒内计数器达到了100,则在这一秒未结束时,之后的请求全部拒绝。
计数器法是一个简单粗暴的方法。也就是因为简单粗暴,会有一定的问题。比如0.9秒时有100个请求,1.1秒时也有100个请求。按照计数器法的计算,第一秒和第二秒确实都在各自的时间范围内限制了100个请求,但是从0.5秒1.5秒这一秒之间有200个请求,这是计数器法的临界问题。如果请求量集中在两个时间窗口的临界点,会产生请求的尖峰。
我们可以引用滑动窗口的方式更加精细的划分时间窗口解决这个问题。将1秒钟细分为10个格子,每个格子用单独的计数器计算当前100毫秒的请求。随着时间的流逝,我们的窗口也跟着时间滑动,每次都是计算最近10个格子的请求量。如果最近10个格子的请求总量超过了100,则下一个格子里就拒绝全部的请求。格子数量越多,我们对流量控制的也就越精细,这部分逻辑可以借助LinkedList来实现。
而滑动窗口的缺点是,需要一直占用内存空间保存最近一个时间窗口内每个格子的请求。
2.漏桶算法
我们想象有一个固定容量的桶,桶底有个洞。请求就是从上往下倒进来的水,可能水流湍急,也可能是涓涓细流。因为桶的容量是固定的,所以灌进来太多的水,溢出去了我们就用不了了。所以无论怎样,桶底漏出来的水,都是匀速流出的。而我们要做的,就是处理这些匀速流出的水就好了。
重点是①流入速率不定②流出速率恒定③只处理流出的请求
漏桶的优点就是,需要处理的请求一直都是固定速率的,特别稳定。而对应的缺点就是,漏桶没有办法解决突发流量的情况。
3.令牌桶算法
相比于漏桶而言,令牌桶的处理方式完全相反。我们想象依旧有一个固定容量的桶,不过这次是以稳定的速率生成令牌放在桶中。当有请求时,需要获取令牌才能通过。因为桶的容量固定,令牌满了就不生产了。桶中有充足的令牌时,突发的流量可以直接获取令牌通过。当令牌取光后,桶空了,后面的请求就得等生成令牌后才能通过,这种情况下请求通过的速率就变得稳定了。
重点是①令牌生成速率固定②能取到令牌即可通过
令牌桶的优点是可用处理突发流量,而且被广泛的应用于各种限流工具中。比如Guava的RateLimiter。
四.基于RateLimiter实现单机限流
- 利用IDEA中的File>New>Project>Spring Initializr
选Spring Web和Lombok
创建好的pom如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>club.westudy</groupId>
<artifactId>limitFlow-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>limitFlow-demo</name>
<description>limitFlow-demo</description>
<properties>
<java.version>11</java.version>
<maven.source>11</maven.source>
<maven.compile>11</maven.compile>
</properties>
<dependencies>
<d

1096

被折叠的 条评论
为什么被折叠?



