我正在整理一个 REST API,由于我不确定它将如何扩展或对它的需求是什么,我希望能够对它的使用进行速率限制以及能够在何时临时拒绝请求盒子容量已满,或者是否存在某种斜线点场景。
当/如果我需要通过添加更多容量来扩展服务时,我还希望能够暂时关闭服务(同时为客户端提供表明主要服务暂时离线的结果)。
这种事情有什么最佳实践吗?实现是带有mysql的Rails。
我正在整理一个 REST API,由于我不确定它将如何扩展或对它的需求是什么,我希望能够对它的使用进行速率限制以及能够在何时临时拒绝请求盒子容量已满,或者是否存在某种斜线点场景。
当/如果我需要通过添加更多容量来扩展服务时,我还希望能够暂时关闭服务(同时为客户端提供表明主要服务暂时离线的结果)。
这种事情有什么最佳实践吗?实现是带有mysql的Rails。
这一切都是通过外部网络服务器完成的,它监听世界(我推荐 nginx 或 lighttpd)。
关于速率限制,nginx可以限制,即每个IP 50 req/minute,全部得到503页面,您可以自定义。
关于预期的临时停机,在 Rails 世界中,这是通过特殊的maintainance.html 页面完成的。当 Rails 应用服务器出现故障时,有某种自动化会创建或符号链接该文件。我建议不要依赖文件存在,而是依赖应用服务器的实际可用性。
但实际上,您可以启动/停止服务而不会丢失任何连接。即,您可以在不同的 UNIX 套接字/IP 端口上运行单独的应用服务器实例,并让平衡器(nginx/lighty/haproxy)也使用该新实例。然后您关闭旧实例,所有客户端都只使用新实例。没有连接丢失。当然,这种情况并不总是可能的,取决于您在新版本中引入的更改类型。
haproxy 是一个仅平衡器的解决方案。它可以非常有效地平衡对农场中应用服务器的请求。
对于相当大的服务,你最终会得到类似的东西:
对于相当小的服务(低于 2K rps),所有的平衡都在一两个网络服务器内完成。
已经有了很好的答案 - 如果您不想自己实现限制器,还有像 3scale ( http://www.3scale.net ) 这样的解决方案,它对 API 进行速率限制、分析等。它使用与 3scale 架构挂钩的插件(请参阅此处了解ruby api 插件)。您也可以通过 varnish 使用它,并让 varnish 充当速率限制代理。
我建议在您的应用程序之外实施速率限制,否则高流量仍然会影响您的应用程序。一个好的解决方案是将它作为你的 apache 代理的一部分来实现,比如mod_evasive