Rails应用程序意外抛出错误

时间:2015-10-22 10:54:37

标签: ruby-on-rails ruby

这是一个奇怪的事情。我可以三次访问同一页面,而这3次中有1次,页面会抛出错误。

这是rails应用程序中的常见问题吗? 这是由于我在某处缓存设置不正确造成的吗?

我知道这里的背景不多,但我觉得这种情况很常见。

我无法完全复制粘贴整个应用程序。

我的错误日志显示为:

ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)):
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:189:in `block in wait_poll'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:180:in `loop'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:180:in `wait_poll'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:135:in `block in poll'
  /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:145:in `synchronize'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:133:in `poll'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:425:in `acquire_connection'
  activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:349:in `block in checkout'
  /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'

1 个答案:

答案 0 :(得分:4)

这不是Rails错误:

  

ActiveRecord :: ConnectionTimeoutError(无法在5.000秒内获得数据库连接(等待5.000秒))

这是您的数据库连接问题:

  • 尝试加载太多数据(IE在几秒钟内将数据库击中数据库以获得1000多条记录)
  • 具有极高延迟(慢)连接
  • 系统上有太多打开的数据库连接(阻止更多加载)

解决此问题的方法是调试程序:

-

<强> DB

您的数据库是如何托管的?

我们使用共享主机存储一些MYSQL数据库用于开发(我们希望保持设置精益),并为生产应用程序提供现场数据库托管(相同的数据中心)。

数据库服务器就像请求JSON对象一样 - SQL delivers "data" in XML,这意味着如果您从本地主机以外的系统请求它,则需要测量多快/慢慢回来。

您的问题可能是您的系统连接到数据库的时间太长,因此刷新可能会阻止它再次访问它。解决这个问题的唯一方法是获得一个地理上接近的设置......

enter image description here

我们之前遇到过Heroku的这个问题 - 使用外部MYSQL db会大大减慢系统速度:)

使用RackSpace之类的东西可以连接到位于同一数据中心的数据库服务器......

enter image description here

-

<强>数据集

根据上述内容,您可能遇到的第二个问题是您正在调用大量数据。

请记住,数据库服务器只是一台计算机,用数据回答您的请求。

因此,如果您在一次通话中调用大量数据,处理它所需的时间将是巨大的(防止进一步处理请求)。

你需要对数据请求保持现实 - 我们倾向于在一次调用中坚持100个对象,你必须避免像瘟疫一样n+1 queries

-

游泳池尺寸

最后,数据库连接的池大小是另一个考虑因素。

您可以在此处阅读:https://devcenter.heroku.com/articles/concurrency-and-database-connections

简而言之,您应该将数据库连接限制为仅限应用程序所需的数据库连接。任何多余的都会引起问题。