【问题标题】:Best practice for rate limiting users of a REST API?REST API 用户速率限制的最佳实践?
【发布时间】:2010-10-11 12:18:41
【问题描述】:

我正在整理一个 REST API,由于我不确定它会如何扩展或对它的需求是什么,我希望能够对它的使用进行速率限制以及能够暂时当盒子超出容量或存在某种斜线场景时拒绝请求。

当/如果我需要通过增加更多容量来扩展服务时,我还希望能够暂时关闭服务(同时向客户端提供指示主要服务暂时离线的结果)。

这种事情有什么最佳实践吗?实现是带有 mysql 的 Rails。

【问题讨论】:

    标签: ruby-on-rails rest scaling capacity


    【解决方案1】:

    我建议在您的应用程序之外实施速率限制,否则高流量仍会影响您的应用程序。一个好的解决方案是将其作为 apache 代理的一部分来实现,例如 mod_evasive

    【讨论】:

    • Apache 不是脱离了高负载领域吗? frankodwyer 肯定需要异步网络来处理大量并发连接,而​​ mpm_event 还不是生产稳定的。当然 apache 可以放在单独的盒子里……买它们只是为了坚持使用 apache 有什么意义吗?
    • 我想这取决于可能的请求量和每个请求对应用程序的成本。以我的经验,apache 可以轻松处理比后端应用程序多几个数量级的请求,这使得位于同一位置的代理很好。
    【解决方案2】:

    这一切都是通过外部网络服务器完成的,它监听世界(我推荐 nginx 或 lighttpd)。

    关于速率限制,nginx可以限制,即每个IP 50 req/minute,全部得到503页面,可以自定义。

    关于预期的临时停机,在 Rails 世界中,这是通过特殊的maintainance.html 页面完成的。当 Rails 应用服务器出现故障时,有某种自动化会创建或符号链接该文件。我建议不要依赖文件存在,而是依赖应用服务器的实际可用性。

    但实际上,您可以启动/停止服务而不会丢失任何连接。 IE。您可以在不同的 UNIX 套接字/IP 端口上运行单独的应用服务器实例,并让平衡器(nginx/lighty/haproxy)也使用该新实例。然后您关闭旧实例,所有客户端都只使用新实例。没有连接丢失。当然,这种情况并不总是可能的,取决于您在新版本中引入的更改类型。

    haproxy 是一个仅平衡器的解决方案。它可以非常有效地平衡对您场中应用服务器的请求。

    对于相当大的服务,你最终会得到类似的东西:

    • api.domain 解析为循环 N 平衡器
    • 每个平衡器代理请求 M 个网络服务器获取静态内容和 P 个应用程序服务器获取动态内容。哦,你的 REST API 没有静态文件,是吗?

    对于非常小的服务(低于 2K rps),所有的平衡都是在一对二的网络服务器内完成的。

    【讨论】:

      【解决方案3】:

      已经有了很好的答案 - 如果您不想自己实现限制器,还有像 3scale (http://www.3scale.net) 这样的解决方案,它可以对 API 进行速率限制、分析等。它使用与 3scale 架构挂钩的插件(请参阅此处的 ruby api plugin)。您也可以通过 varnish 使用它,并让 varnish 充当速率限制代理。

      【讨论】:

        猜你喜欢
        • 2018-05-25
        • 1970-01-01
        • 2013-10-23
        • 2020-05-29
        • 1970-01-01
        • 1970-01-01
        • 2018-04-27
        • 2020-04-23
        相关资源
        最近更新 更多