java - 构建自定义过滤器以每个标识符在 M 个时间单位内处理 N 个请求
问题描述
我正在尝试构建一个自定义过滤器,该过滤器将仅在每个标识符的每 M 时间单位(例如 1 秒)处理 N 个请求(例如 100 个)。所有大于 N 的请求都将被拒绝或忽略。请求是一个包含标识符、时间戳和其他卫星数据的对象(过滤器不应处理卫星数据)。
首先想到的是有一个 ConcurrentHashMap[String, AtomicInteger] ,它会有每个标识符的请求数,但是我无法理解使用哪个数据结构来跟踪每秒这些计数,并且这个数据结构也应该能够清理因为它很快就会增长,我们不需要维护过去的数据。
这也意味着一个可能的解决方案将具有一个数据结构,该结构能够仅存储时间戳之间的增量,并确保每个标识符在 M 个时间单位内其不大于 N 个请求。
这听起来像是一个速率限制器,并且可能有标准库或可用选项,但我想了解如何构建它,因此寻找一些指针而不是直接代码解决方案。
解决方案
这是一种方法。
存储形式为 的值(time_rounded_off, count)
。仅当time_rounded_off = current_time_rounded_off
和时才处理请求count < max_count
。
当舍入时间增加时,计数器将重置为 0,然后您再次开始处理。
这种设计有利于保持业务规则到位,但如果处理突然爆发的请求对您的基础架构来说太难了,那就不好了。为此,我建议您对每秒处理的请求数保持指数移动平均值。只要它下降到足够低,您就可以接受另一个请求。
使用这种方法,您的值将是表单的对(timestamp, average)
。现在更新它的过程是将时间戳更新为当前时间戳,并将平均值乘以衰减因子(取决于时间戳的差异)。如果您收到请求的速度超过了它可以处理的速度,结果将以正确的近似速率对它们进行采样。
您现在有两个参数可以使用,衰减率和平均值。您可以选择特定的速率,即每小时 360,000 次、每分钟 6000 次、每秒 100 次和每 0.1 秒 10 次。它们之间的区别在于您必须一次性处理的“突发”的潜在大小。
推荐阅读
- java - 参数为空时的Spring Cloud feign行为
- c# - 找不到适用于 .net 示例的 aws 转录
- drupal - 如何将内容查看为 Drupal 8 视图的翻译
- c++ - 从排序数组中删除重复项,不同代码方式的相同解决方案具有不同的输出
- c# - C# MongoDB 加入集合并包含过滤器
- r - R面板数据集查找所有时变变量
- c++ - POCO 等 C++ 库如何访问网络?
- flutter - Flutter:onRefresh 回调返回 null
- docker - Azure 管道从错误的 Dockerfile 构建映像
- node.js - 使用 Knex 连接到服务器,如何解决错误未处理的拒绝错误:密码验证失败