【问题标题】:Techniques to measure/enforce a quota on customer web requests衡量/强制执行客户 Web 请求配额的技术
【发布时间】:2015-11-05 12:19:31
【问题描述】:

我有一个用于 B2B 应用程序的 Web 应用程序,该应用程序具有多个同类 Web 前端(具体来说,我在 App Engine 上运行)。我需要设计一个短期配额系统,以便在客户的突发请求率超过其配额时拒绝流量。需要支持的客户数量在数万范围内。我想衡量这些配额的时间范围将在“分钟”范围内;最多一个小时。

例如如果时间尺度是 10 分钟,并且客户 X 提出的请求远远超过了他们的配额,那么我可以让系统为他们的 所有 请求提供服务,直到他们用完每 10 次允许的请求数量分钟,然后拒绝他们在该 10 分钟窗口剩余时间内的所有请求,然后在接下来的 10 分钟窗口中重新开始该过程。

我考虑过的半生不熟的解决方案:

  • 买一个强大的 Redis 盒子。在来自客户 X 的每个请求(或者可能是其中的某个固定百分比,例如 1-in-10,以减轻负载)时,将 GET 设置为 X 计数变量。如果 > 他们的每 10 分钟配额,则拒绝该请求。否则,对 count-of-X 变量进行 INCR 并为请求提供服务。每 10 分钟,将所有客户的计数设置为 0。

  • 与上面类似,除了使用 memcache,因为该服务内置在应用引擎中,所以我不需要运行自己的盒子。如果 memcache 值丢失了,哦,好吧——我们可能不会在那个时间窗口内像我们应该的那样节流(只要时间窗口足够短,我们可能不会太在意)。

  • 每个网络服务器都存储全球每个客户的计数器,用于 new-requests-seen-by-me 和 requests-seen-globally。每一秒(左右),每个网络服务器都会将其 new-requests-seen-by-me 值(针对每个客户)推送到某个集中的类似 pub-sub 的服务,该服务将该值重新分配给所有网络服务器(它们添加到他们的 requests-seen -全球价值)。 Web 服务器使用他们的 requests-seen-globally 值(总是有点陈旧)来决定是服务还是拒绝请求。

【问题讨论】:

  • 多少流量?大多数人只需将计数器保存在数据库中就可以了。但是,如果您预计每分钟有数百万个请求,您可能需要做一些更聪明的事情......
  • 呃——抱歉。显而易见的事情要省略。对于我在这里关注的特定类型的请求,我们预计某些客户将产生高达 50/秒的请求。这对于应用引擎数据存储来说太高了(它只支持对单个实体的约 5 次写入/秒的速率),但肯定可以通过 Redis 或 Cassandra 之类的东西来管理。
  • 然后我会使用内存缓存。它会工作得很好。如果它是 Redis 或 memcache 的一个偶数选择,我会选择 Redis,但一个更容易。选项#3 适合严重的规模。您没有考虑的一个选项是让负载平衡器将用户与服务器联系起来。这简化了这一点,因为现在服务器应该知道所有用户请求。并且可以保持其他类型的用户状态。

标签: algorithm webserver quota


【解决方案1】:

Memcache 适用于这种方案,但使用原子增量和获取。

但是,请注意,10 分钟窗口的限制对于保护您的系统免受过载影响不大。至少,您应该在整个窗口期内的不同时间(随机或仔细选择)重置客户计数,这样您就不会同时被所有客户超载。如果您有足够多的客户,这将确保负载在一定程度上分布均匀。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2018-11-29
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多