【问题标题】:slow post request RoR缓慢的发布请求 RoR
【发布时间】:2012-03-30 12:48:40
【问题描述】:

我在 RoR 应用中遇到了缓慢的发布请求问题。 该项目是一个分布式系统,客户端发送大量照片,服务器将这些照片保存在数据库中。 我使用MySql server 5.1,客户端和服务器都在同一个本地网络中,他们是RoR中的程序员...... 客户端在一个请求中发送 10 张照片。 10 张照片以 yaml 格式以数组结构发送。 请求是:

res = Net::HTTP.post_form(uri, :mac => 'String', :value => 'Yaml_array_images_data', :num => 10)

日志说:

`Started POST "/events/save_photo" for 192.168.0.113 at 2012-03-30 09:45:10 +0200
  Processing by EventsController#save_photo as */*
  Parameters: {"data_type"=>"image", "value"=>"--- \n- !binary |\n  /9j/2wCEAAoH
BwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYI...", "created_at"=>"--- \n- 2012-03-30 09:26:29 +02:00 \n-....", "mac"=>"00606E91E5D2"}
(0.3ms)  SET PROFILING=1
  Device Load (1.2ms)  SELECT SQL_NO_CACHE `devices`.* FROM `devices` 
WHERE `devices`.`mac` = '00606E91E51E' LIMIT 1
  CACHE (0.0ms)  SELECT `devices`.* FROM `devices` WHERE `devices`.
`mac` = '00606E91E51E' LIMIT 1
   (0.3ms)  BEGIN
  SQL (2.9ms)  INSERT INTO `multimedia` (`created_at`, `data`, `eve
nt_id`, `updated_at`) VALUES ('2012-03-30 07:45:00', x'f22b19237b63f1c8c40da49ae
5eb68969dd3cf28193ba6a3704fe2f286494439eea4f9071bb6ef9de530ccaaab235a402e2d94aad
2f4f1b90df022c23078f543bc6ca1c6fe8b17af45eae865bb....)
(0.3ms)  SET PROFILING=1
  Device Load (1.2ms)  SELECT SQL_NO_CACHE `devices`.* FROM `devices` 
WHERE `devices`.`mac` = '00606E91E51E' LIMIT 1
  CACHE (0.0ms)  SELECT `devices`.* FROM `devices` WHERE `devices`.
`mac` = '00606E91E51E' LIMIT 1
   (0.3ms)  BEGIN
  SQL (2.9ms)  INSERT INTO `multimedia` (`created_at`, `data`, `eve
nt_id`, `updated_at`) VALUES ('2012-03-30 07:45:00', x'f22b19237b63f1c8c40da49ae
5eb68969dd3cf28193ba6a3704fe2f286494439eea4f9071bb6ef9de530ccaaab235a402e2d94aad
2f4f1b90df022c23078f543bc6ca1c6fe8b17af45eae865bb...)
(44.0ms)  COMMIT
   (0.3ms)  BEGIN
  SQL (0.8ms)  INSERT INTO `events` (`created_at`, `data_type`, `devic
e_id`, `element_id`, `multimedia_id`, `name`, `status`, `updated_at`, `value`) V
ALUES ('2012-03-30 07:45:00', 'image', 19, 413397, 1066303, 'photo', NULL, '2012
-03-30 07:45:11', '--- 0\n...\n')
   (38.2ms)  COMMIT
   (0.3ms)  BEGIN
  SQL (2.9ms)  INSERT INTO `multimedia` (`created_at`, `data`, `eve
nt_id`, `updated_at`) VALUES ('2012-03-30 07:45:01', x'f22b19237b63f1c8c40da49ae
5eb68969dd3cf28193ba6a3704fe2f28...)
....
for 10 times insert a record in multimedia and one in events table
...
(33.0ms)  COMMIT
   (0.3ms)  BEGIN
   (0.4ms)  SET PROFILING=1
   (1.3ms)  SELECT SQL_NO_CACHE 1 FROM `devices` WHERE (`devices`.`mac
` = BINARY '00606E91E51E' AND `devices`.`id` != 19) LIMIT 1
   (0.7ms)  UPDATE `devices` SET `elem_photo_id` = 413408, `updated
_at` = '2012-03-30 07:45:12' WHERE `devices`.`id` = 19
   (34.5ms)  COMMIT
Rendered events/save_photo.html.erb (0.2ms)
Completed 200 OK in 1957ms (Views: 10.2ms | ActiveRecord: 1466.6ms)`

我的第一个问题是总时间以及查看时间和活动记录时间之和之间的差异。

之后这个时间在服务器的日志中,所以这些是请求的执行时间。如果我花时间,在客户端,从发送请求到接收响应,是 3,6 秒!为什么?我认为在本地网络中传输 200k 不需要 2 秒!

【问题讨论】:

标签: ruby-on-rails post request


【解决方案1】:

客户端发送请求和服务器发送响应之间发生了很多事情

仅举几例:

  1. 客户端解析dns(通常是缓存的)
  2. 客户端发起http连接
  3. 客户端实际发布数据
  4. 您拥有的任何服务器都接受发布请求并将其排入队列以由您的 Rails 堆栈处理
  5. 在实际访问控制器之前,请求会通过您拥有的所有机架中间件
  6. 控制器处理您的请求并生成响应
  7. 响应随后被传输到客户端,浏览器解析并呈现它

您在服务器日志中看到的可能只有第 6 点,其他一切都取决于您的应用设置和响应属性(包含大量 css、javascript、图像等的 html)

关于您在这一行中的时差问题:

Completed 200 OK in 1957ms (Views: 10.2ms | ActiveRecord: 1466.6ms)

详细的时间消耗(括号内)并不完全详细。它缺少 GC 时间(如果您将文件作为 yaml 格式的参数发送,它可能会被调用),它也缺少在您的前置过滤器和操作本身中花费的时间。

【讨论】:

  • mmmm....好吧....我想是这样的....但我什至会设置我的 sqtup...但我不知道我在哪里寻找.是否有关于此的指南?例如我对 DNS 不感兴趣.....
  • 这一切都取决于您使用的 http 服务器(nginx/apache/etc)、为您的 rails 应用程序服务的内容(unicorn/thin/passenger/etc)、您拥有的中间件rake middleware。在您的应用程序中,我想最简单的方法是在任何地方记录时间戳并查看时间花在哪里。或者您可以使用 perftools.rb gem 来实际分析您的应用程序。
  • 我使用 apache2 服务器,乘客和 rake 中间件命令返回我:使用 ActionDispatch::Static 使用 Rack::Lock 使用 #<:cache::strategy::localcache::middleware:0x9f78a4c> 使用 Rack::Runtime 使用 Rack::MethodOverride 使用 Rails::Rack::Logger 使用 ActionDispatch::ShowExceptions 使用 ActionDispatch::RemoteIp 使用 Rack::Sendfile 使用 ActionDispatch::Reloader 使用 ActionDispatch::Callbacks 使用 ActiveRecord::ConnectionAdapters: :ConnectionManagement 使用 ActiveRecord::QueryCache 使用 ActionDispatch::Cookies 使用 ActionDispatch::Session::CookieStore
  • 使用 ActionDispatch::Flash 使用 ActionDispatch::ParamsParser 使用 ActionDispatch::Head 使用 Rack::ConditionalGet 使用 Rack::ETag 使用 ActionDispatch::BestStandardsSupport 运行 IdePro::Application.routes 以获取时间在发送请求之前使用时间戳: start = Time.now.to_f 在发送请求之前停止 = Time.now.to_f 之后响应最终到达 make durata = stop - start
猜你喜欢
  • 1970-01-01
  • 2016-04-15
  • 2014-04-21
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多