#rate-limiting #limiter #redis #key #backed #counter #fixed

限制

使用Redis支持的固定窗口计数器对任意键进行速率限制

2次发布

0.1.1 2019年10月20日
0.1.0 2019年10月20日

#896 in 异步

Download history 6/week @ 2024-03-10 3/week @ 2024-03-24 53/week @ 2024-03-31 2/week @ 2024-04-07

每月192次下载
2个crate中使用(通过limitation-actix-middlewa…

MPL-2.0许可协议

40KB
273

限制

CI CI Status
最新版本 Latest version
文档 Documentation
crate下载 Crate downloads
许可协议 Crate license

目录

使用Redis支持的固定窗口计数器对任意键进行速率限制。

关于

此库为任意键提供由Redis实例支持的固定窗口计数器。周期长度和每个周期的最大限制可以在设置时配置。与后端的通信以非阻塞、异步的方式进行,允许库与Tokio、Actix等其他异步框架配合使用。

注意:当前使用的是预-async/await Futures(即Futures 0.1.x),但随着Rust 1.39.0的发布,这可能在不久的将来升级。

用法

limitation添加到您的Cargo.toml

[dependencies]
limitation = "0.1.1"

快速示例

Limiter的主要类型使用构建器构建自身。构建完成后,使用表示用户、会话、交互等的键的count方法。请注意,count是Future,因此必须由运行时驱动完成。例如,要在一个键"10.0.0.5"上运行一个计数

use limitation::Limiter;
use futures::Future;

// Build a Limiter with a default rate with a local running Redis instance
let limiter = Limiter::build("redis://127.0.0.1/").finish()?;
// The key to count and track
let key = "10.0.0.5";

// Start and run a Tokio runtime to drive the Future to completion
tokio::run(
    limiter
        // Count returns a Status if the key is under the limit and an `Error::LimitExceeded`
        // containing a Status if the limit has been exceeded
        .count(key)
        // This example deals with both limit exceeded and any Redis connection issues. In this
        // case we'll print the error to the standard error stream to show the current limit
        // status
        .map_err(|err| eprintln!("err: {}", err))
        // In this case we are under the limit and can print out the limit status to the
        // standard output stream
        .and_then(|status| {
            println!("ok: {:?}", status);
            Ok(())
        }),
);

限制构建器

Limiter的构建器有2个设置,可以根据用例进行自定义

  • limit:周期内请求数量的峰值。默认值为5000
  • period:周期窗口的Duration。默认值为60分钟。
use limitation::Limiter;
use std::time::Duration;

let limiter = Limiter::build("redis://127.0.0.1/")
    .limit(5)
    .period(Duration::from_secs(10))
    .finish()?;

示例

该库的一个简单示例可以在limitation-example中找到。

实现的主要灵感来自一篇名为使用NodeJS和Redis构建简单API速率限制器的替代方法的博客文章,作者是Atul R

为该库使用的其他研究和参考资料

想法和未来工作

以下是一些关于本项目的想法和潜在的未来工作。如果你正在阅读此内容,那么你可能对此感兴趣或想帮忙?太好了!请务必查看贡献部分并深入了解!

  • 调查并提供替代的速率限制算法,尤其是滑动窗口解决方案。
  • 使用bb8bb8-redis包添加异步Redis连接池,以减少连接建立延迟。
  • Limiter上添加一个status方法,该方法返回密钥的Status而无需计数请求。
  • 在集成测试套件中添加对RedisServer的支持,类似于redis包中的基础设施。

CI状态

构建(master分支)

操作系统 稳定的Rust 夜间Rust MSRV
FreeBSD FreeBSD Stable Build Status FreeBSD Nightly Build Status FreeBSD Oldest Build Status
Linux Linux Stable Build Status Linux Nightly Build Status Linux Oldest Build Status
macOS macOS Stable Build Status macOS Nightly Build Status macOS Oldest Build Status
Windows Windows Stable Build Status Windows Nightly Build Status Windows Oldest Build Status

测试(master分支)

操作系统 稳定的Rust 夜间Rust MSRV
FreeBSD FreeBSD Stable Test Status FreeBSD Nightly Test Status FreeBSD Oldest Test Status
Linux Linux Stable Test Status Linux Nightly Test Status Linux Oldest Test Status
macOS macOS Stable Test Status macOS Nightly Test Status macOS Oldest Test Status
Windows Windows Stable Test Status Windows Nightly Test Status Windows Oldest Test Status

检查(master分支)

状态
lint Lint Status
格式 Format Status

行为准则

本项目遵循贡献者公约行为准则。通过参与,你应遵守此准则。如有不适当行为,请联系[email protected]

问题

如果你对本项目有任何问题或疑问,请通过GitHub问题联系我们。

贡献

欢迎你为新功能、修复或更新做出贡献,无论大小;我们总是很高兴收到拉取请求,并尽最大努力尽快处理。

在你开始编码之前,我们建议通过GitHub问题讨论你的计划,特别是对于更具雄心的贡献。这给其他贡献者一个机会,指明正确的方向,对你的设计提供反馈,并帮助你确定是否有人正在做同样的事情。

发布历史

查看变更日志以获取完整的发布历史。

作者

Fletcher Nichol ([email protected])创建和维护。

许可协议

在Mozilla公共许可证第2版(LICENSE.txt)下许可。

除非你明确声明,否则任何有意提交以包含在本作品中的贡献(根据MPL-2.0许可证的定义),都应按上述方式许可,不附加任何额外的条款或条件。

依赖关系

~8MB
~162K SLoC