measure/enforce 客户 Web 请求配额的技巧
Techniques to measure/enforce a quota on customer web requests
我有一个用于 B2B 应用程序的 Web 应用程序,其中包含多个同质 Web 前端(具体来说,我 运行 在 App Engine 上使用)。我需要设计一个短期配额系统,以便在客户的突发请求率超过他们的配额时拒绝流量。需要支持的客户数量在数万范围内。我要衡量这些配额的时间尺度将在 "minutes" 范围内;最多一个小时。
例如如果时间范围是 10 分钟并且客户 X 提出的请求远远超过他们的配额,那么我可以接受系统服务 all 他们的请求,直到他们用完他们的请求数量每 10 分钟允许一次,然后在剩下的 10 分钟 window 中拒绝他们的所有请求,然后在接下来的 10 分钟 window.
中重新开始该过程
我考虑过的半生不熟的解决方案:
获得一个强大的 Redis 盒子。对于来自客户 X 的每个请求(或者可能是其中的某个固定百分比,例如十分之一,以减轻负载),对 X 计数变量进行 GET。如果超过他们的每 10 分钟配额,则拒绝该请求。否则,对 count-of-X 变量进行 INCR 并提供请求。每 10 分钟,将所有客户的计数设置为 0。
与上面类似,除了使用内存缓存,因为该服务内置于应用程序引擎中,所以我不需要 运行 我自己的盒子。如果 memcache 值丢失,哦,好吧 - 我们可能不会像我们应该在那段时间 window 那样节流(只要时间 window 足够短,我们可能不会太在意)。
每个网络服务器都存储全球每个客户的计数器,用于我看到的新请求和全局看到的请求。每隔一秒(左右),每个网络服务器都会将其新的“我看到的请求”值(针对每个客户)推送到一些类似 pub-sub 的集中式服务,该服务将该值重新分配给所有网络服务器(他们将其添加到他们的“看到的请求”中) - 全球价值)。网络服务器使用他们的全局请求值(总是有点陈旧)来决定是服务还是拒绝请求。
Memcache 适用于这种方案,但使用原子增量和获取。
但是请注意,10 分钟的限制 window 对保护您的系统免受过载没有太大作用。至少,您应该在整个 window 期间的不同时间(随机或精心选择)重置客户数量,这样您就不会同时被所有客户压得喘不过气来。如果您有足够的客户,这将确保负载稍微均匀分布。
我有一个用于 B2B 应用程序的 Web 应用程序,其中包含多个同质 Web 前端(具体来说,我 运行 在 App Engine 上使用)。我需要设计一个短期配额系统,以便在客户的突发请求率超过他们的配额时拒绝流量。需要支持的客户数量在数万范围内。我要衡量这些配额的时间尺度将在 "minutes" 范围内;最多一个小时。
例如如果时间范围是 10 分钟并且客户 X 提出的请求远远超过他们的配额,那么我可以接受系统服务 all 他们的请求,直到他们用完他们的请求数量每 10 分钟允许一次,然后在剩下的 10 分钟 window 中拒绝他们的所有请求,然后在接下来的 10 分钟 window.
中重新开始该过程我考虑过的半生不熟的解决方案:
获得一个强大的 Redis 盒子。对于来自客户 X 的每个请求(或者可能是其中的某个固定百分比,例如十分之一,以减轻负载),对 X 计数变量进行 GET。如果超过他们的每 10 分钟配额,则拒绝该请求。否则,对 count-of-X 变量进行 INCR 并提供请求。每 10 分钟,将所有客户的计数设置为 0。
与上面类似,除了使用内存缓存,因为该服务内置于应用程序引擎中,所以我不需要 运行 我自己的盒子。如果 memcache 值丢失,哦,好吧 - 我们可能不会像我们应该在那段时间 window 那样节流(只要时间 window 足够短,我们可能不会太在意)。
每个网络服务器都存储全球每个客户的计数器,用于我看到的新请求和全局看到的请求。每隔一秒(左右),每个网络服务器都会将其新的“我看到的请求”值(针对每个客户)推送到一些类似 pub-sub 的集中式服务,该服务将该值重新分配给所有网络服务器(他们将其添加到他们的“看到的请求”中) - 全球价值)。网络服务器使用他们的全局请求值(总是有点陈旧)来决定是服务还是拒绝请求。
Memcache 适用于这种方案,但使用原子增量和获取。
但是请注意,10 分钟的限制 window 对保护您的系统免受过载没有太大作用。至少,您应该在整个 window 期间的不同时间(随机或精心选择)重置客户数量,这样您就不会同时被所有客户压得喘不过气来。如果您有足够的客户,这将确保负载稍微均匀分布。