Skip to main content

Distributed Rate Limiter 限流器

1. Single Node 单机 - Guava RateLimiter

让我们考虑一个常见的场景:一个 RESTful API 服务器,它提供了一个查询数据的端点。但是,为了防止滥用,我们希望限制每秒的请求数量。

  • rateLimiter.acquire(): Tries to get a token. If none are available, it will wait and block the program. 如果没有可用的令牌,它会阻塞直到有令牌可用或者超时。
  • rateLimiter.tryAcquire(): Tries to get a token. If none are available, it returns false right away. 如果没有可用的令牌,它会立即返回false而不是阻塞。
  • RateLimiter.create(5.0): It will add 5 tokens every seacond. 每秒产生5个令牌。
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

// 创建一个每秒产生5个令牌的RateLimiter
private static final RateLimiter rateLimiter = RateLimiter.create(5.0);

@GetMapping("/data")
public String fetchData() {
if (!rateLimiter.tryAcquire()) {
return "Too many requests. Please try again later.";
}
// 正常处理逻辑
return "Data fetched successfully!";
}
}

2. Tools needed 准备工作

2.1 Apache Bench

ab is a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server. It is designed to give you an impression of how your current Apache installation performs.

ab 是一个用于对 Apache 超文本传输协议 (HTTP) 服务器进行基准测试的工具

How to use

# -n 表示请求数,-c 表示并发数
ab -n 100 -c 10 http://www.imooc.com/

-n  即requests,用于指定压力测试总共的执行次数。
-c 即concurrency,用于指定的并发数。
-t 即timelimit,等待响应的最大时间(单位:秒)。
-b 即windowsize,TCP发送/接收的缓冲大小(单位:字节)。
-p 即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数。
-u 即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数。
-T 即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain。
-v 即verbosity,指定打印帮助信息的冗余级别。
-w 以HTML表格形式打印结果。
-i 使用HEAD请求代替GET请求。
-x 插入字符串作为table标签的属性。
-y 插入字符串作为tr标签的属性。
-z 插入字符串作为td标签的属性。
-C 添加cookie信息,例如:"Apache=1234"(可以重复该参数选项以添加多个)。
-H 添加任意的请求头,例如:"Accept-Encoding: gzip",请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)。
-A 添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开。
-P 添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开。
-X 指定使用的和端口号,例如:"126.10.10.3:88"。
-V 打印版本号并退出。
-k 使用HTTP的KeepAlive特性。
-d 不显示百分比。
-S 不显示预估和警告信息。
-g 输出结果信息到gnuplot格式的文件中。
-e 输出结果信息到CSV格式的文件中。
-r 指定接收到错误信息时不退出程序。
-h 显示用法信息,其实就是ab -help。

3. Distributed 分布式 - Alibaba Sentinel

GitHub: https://github.com/alibaba/Sentinel

As distributed systems are becoming increasingly popular, the reliability between services is becoming more important than ever before. Sentinel is a powerful flow control component that takes "flow" as the breakthrough point and covers multiple fields including flow control, concurrency limiting, circuit breaking, and adaptive system protection to guarantee the reliability of microservices.

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

3.1 Sentinel Dashboard 控制台

  • 从 release 页面下载控制台的 jar 包
  • 或者下载源码,使用 maven 打包 mvn clean package -DskipTests

Run the Dashboard 启动

# 官方版本命令 not work
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

# 指定允许 Java 版本后, it works
java -Dserver.port=9000 -Dcsp.sentinel.dashboard.server=localhost:9000 -Dproject.name=sentinel-dashboard --add-opens java.base/java.lang=ALL-UNNAMED -jar sentinel-dashboard-1.8.0.jar

启动后,访问 http://localhost:9000,默认用户名密码都是 sentinel.

References