请求外部服务 (S3) 花费太多时间
Request to External Service (S3) takes too much time
我已经为此苦苦挣扎了 2 天,我只是想不出我应该做什么。我正在使用 Rails (4.2.3) 和 Ruby 2.2.1,如果有任何帮助的话。
安装新遗物后 gem 我发现我的两个控制器需要很长时间才能响应(~17 秒)的原因是对 amazon s3 的请求。
那些页面仅显示 10 条记录使用 ransack gem。
这里有截图给大家看。
任何帮助将不胜感激...
New Relic external services screenshot
像 S3 这样的外部服务调用可能需要时间,具体取决于多个变量,例如:
- 网络路由 b/w 您的服务器到 S3。检查
traceroute
- 延迟 b/w 服务器。
ping
越高,建立连接的时间越长。
- AWS S3 端的健康 - 如果他们的服务遇到问题,您的服务可能会受到影响
- 等..
通常建议在后台执行 image/file resize/upload 等任务。 Resque, Sidekiq 之类的 Gem 正是用来做到这一点的。
很难准确地说,有 10 条记录,每条记录 1.7 秒似乎相当大,也许你应该在 Rails 之外测量它(例如,直接在浏览器中请求相同的 URL)。
但通常在控制器中发出 10 个顺序请求是一件坏事。即使请求相当快,发出 10 个请求也可能是该响应中最慢的请求的很多倍。
- 您可以通过每个生成 10 个线程来获取记录,然后加入并呈现视图来完成此操作。
- 或者您可以异步获取每条记录(非阻塞,因此所有 10 条记录同时发生)。
- 或者,如果您可以在页面中呈现具有 AJAX/XHR 响应的数据,请让控制器仅获取 1 个项目并让应用程序单独请求所有 10 个(但您将达到浏览器对域的最大请求限制所以不会得到完整的 10 倍加速。
- 如果浏览器不需要立即响应,请使用后台任务运行程序(许多 Gems)并告诉浏览器 "its pending"。这将避免阻止您的 Rails 服务器,但从单个用户的角度来看甚至可能 更慢 。
不幸的是,Ruby/Rails 中的异步支持不是很好(猜测需要更多的人提出要求和贡献)。我认为 AWS SDK 根本不可能使用选项 2,您需要四处寻找真正异步的 HTTP 客户端库才能在低级别执行此操作(而不仅仅是 thread/fibre 包装器)。
我已经为此苦苦挣扎了 2 天,我只是想不出我应该做什么。我正在使用 Rails (4.2.3) 和 Ruby 2.2.1,如果有任何帮助的话。
安装新遗物后 gem 我发现我的两个控制器需要很长时间才能响应(~17 秒)的原因是对 amazon s3 的请求。
那些页面仅显示 10 条记录使用 ransack gem。
这里有截图给大家看。
任何帮助将不胜感激...
New Relic external services screenshot
像 S3 这样的外部服务调用可能需要时间,具体取决于多个变量,例如:
- 网络路由 b/w 您的服务器到 S3。检查
traceroute
- 延迟 b/w 服务器。
ping
越高,建立连接的时间越长。 - AWS S3 端的健康 - 如果他们的服务遇到问题,您的服务可能会受到影响
- 等..
通常建议在后台执行 image/file resize/upload 等任务。 Resque, Sidekiq 之类的 Gem 正是用来做到这一点的。
很难准确地说,有 10 条记录,每条记录 1.7 秒似乎相当大,也许你应该在 Rails 之外测量它(例如,直接在浏览器中请求相同的 URL)。
但通常在控制器中发出 10 个顺序请求是一件坏事。即使请求相当快,发出 10 个请求也可能是该响应中最慢的请求的很多倍。
- 您可以通过每个生成 10 个线程来获取记录,然后加入并呈现视图来完成此操作。
- 或者您可以异步获取每条记录(非阻塞,因此所有 10 条记录同时发生)。
- 或者,如果您可以在页面中呈现具有 AJAX/XHR 响应的数据,请让控制器仅获取 1 个项目并让应用程序单独请求所有 10 个(但您将达到浏览器对域的最大请求限制所以不会得到完整的 10 倍加速。
- 如果浏览器不需要立即响应,请使用后台任务运行程序(许多 Gems)并告诉浏览器 "its pending"。这将避免阻止您的 Rails 服务器,但从单个用户的角度来看甚至可能 更慢 。
不幸的是,Ruby/Rails 中的异步支持不是很好(猜测需要更多的人提出要求和贡献)。我认为 AWS SDK 根本不可能使用选项 2,您需要四处寻找真正异步的 HTTP 客户端库才能在低级别执行此操作(而不仅仅是 thread/fibre 包装器)。