首页 > 解决方案 > 构建自定义过滤器以每个标识符在 M 个时间单位内处理 N 个请求

问题描述

我正在尝试构建一个自定义过滤器,该过滤器将仅在每个标识符的每 M 时间单位(例如 1 秒)处理 N 个请求(例如 100 个)。所有大于 N 的请求都将被拒绝或忽略。请求是一个包含标识符、时间戳和其他卫星数据的对象(过滤器不应处理卫星数据)。

首先想到的是有一个 ConcurrentHashMap[String, AtomicInteger] ,它会有每个标识符的请求数,但是我无法理解使用哪个数据结构来跟踪每秒这些计数,并且这个数据结构也应该能够清理因为它很快就会增长,我们不需要维护过去的数据。

这也意味着一个可能的解决方案将具有一个数据结构,该结构能够仅存储时间戳之间的增量,并确保每个标识符在 M 个时间单位内其不大于 N 个请求。

这听起来像是一个速率限制器,并且可能有标准库或可用选项,但我想了解如何构建它,因此寻找一些指针而不是直接代码解决方案

标签: javamultithreadingalgorithmfilter

解决方案


这是一种方法。

存储形式为 的值(time_rounded_off, count)。仅当time_rounded_off = current_time_rounded_off和时才处理请求count < max_count

当舍入时间增加时,计数器将重置为 0,然后您再次开始处理。

这种设计有利于保持业务规则到位,但如果处理突然爆发的请求对您的基础架构来说太难了,那就不好了。为此,我建议您对每秒处理的请求数保持指数移动平均值。只要它下降到足够低,您就可以接受另一个请求。

使用这种方法,您的值将是表单的对(timestamp, average)。现在更新它的过程是将时间戳更新为当前时间戳,并将平均值乘以衰减因子(取决于时间戳的差异)。如果您收到请求的速度超过了它可以处理的速度,结果将以正确的近似速率对它们进行采样。

您现在有两个参数可以使用,衰减率和平均值。您可以选择特定的速率,即每小时 360,000 次、每分钟 6000 次、每秒 100 次和每 0.1 秒 10 次。它们之间的区别在于您必须一次性处理的“突发”的潜在大小。


推荐阅读