【问题标题】:Rails 4 database connection pool errorRails 4 数据库连接池错误
【发布时间】:2014-09-14 17:13:02
【问题描述】:

我有一个使用 NGINX 和 Puma 托管的 rails 应用程序。每隔 10 小时左右,该应用程序就会变得无法使用。每当用户尝试连接时,都会显示以下错误消息:

Error during failsafe response: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)

这会一直持续到应用重新启动。

我读到这是因为数据库连接池已满,因此必须在 rails 应用程序中创建线程,这些线程在完成时不会关闭它们与数据库的连接。 据我所知,应用程序代码中只有一处使用了线程:一个块使用了 Ruby Timeout 模块,但这并不访问数据库。

遵循本指南 https://devcenter.heroku.com/articles/concurrency-and-database-connections(我实际上并没有使用 Heroku) 我已使用以下配置文件将数据库连接池的大小设置为 5:

#config/initializers/database_connection.rb
Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    config = ActiveRecord::Base.configurations[Rails.env] ||
                Rails.application.config.database_configuration[Rails.env]
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    config['pool']              = ENV['MAX_THREADS'] || 5 
    ActiveRecord::Base.establish_connection(config)
  end

结束

该网站使用 Rails 4.0.0 托管。我已经读到这实际上可能是 Rails 4.0.0 的问题,并且在以后的版本中已修复,但我不确定。 ConnectionTimeoutError on Heroku with Postgres

  1. 有什么方法可以监控连接池中的活动数据库连接数吗?这将使调试变得更加容易。
  2. 在 Rails 应用程序代码中使用 Timeout 模块是否可能导致此问题?
  3. 这可能是 Rails 4.0.0 的问题,而不是我的应用程序的问题吗?

rails 应用正在生产环境中运行。如果需要,我可以提供有关我的 Puma、NGINX 配置的更多信息。

【问题讨论】:

  • 我在 4.1 应用程序上也看到了很多这样的问题,而我在 3.x 上从未见过,所以我认为问题并没有真正解决。
  • 有人找到解决办法吗?我也在看这个。我有预感它与airbrake gem 和/或在application_controller.rb 中使用current_user 相关联。其他任何人在使用 airbrake gem 或在 application_controller.rb 中使用 current_user 时遇到此错误?
  • 通过将我的开发服务器切换到 webrick 我没有看到这个错误。我认为罪魁祸首是美洲狮。

标签: ruby-on-rails nginx database-connection puma


【解决方案1】:

故障安全响应试图分配数据库连接这一事实可能是确凿的证据。它可能会帮助您描述故障保护响应中发生的情况。故障安全响应可能是在原始请求触发异常时触发的。在 ConnectionManager 调用 clear_active_connections 之后调用调用故障安全响应的 rails show_exception 例程!对于当前请求(因异常而失败),这意味着在故障保护响应失败后,rails 不会自动释放数据库连接。这意味着故障安全响应处理程序负责清理自己的数据库连接。我不确定故障安全响应处理程序尝试连接到数据库是否是一种好习惯,但如果这是所需的行为,那么您可能必须调用 clear_active_connections!在您的故障安全处理程序的末尾显式地(在确保块中)。

我一直在调查我自己的应用程序中的一个类似问题,发现这是关于连接如何工作的有用指南:https://bibwild.wordpress.com/2014/07/17/activerecord-concurrency-in-rails4-avoid-leaked-connections/。虽然此处引用的代码可能需要进行一些调整,但其中有一个很好的概述,说明了如何检测何时创建隐式数据库连接。

【讨论】:

    【解决方案2】:

    我不认为这是 rails 4.0.0 的问题。

    正如ruby timeout module documentation 中提到的,它产生了一个新线程。我认为它有可能产生长时间运行的线程来保持数据库连接。要检查正在运行的线程,您可以使用Thread.list 方法。另请记住,您的池大小必须大于 puma 线程乘以 puma 工人。

    【讨论】:

      猜你喜欢
      • 2015-04-08
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 2014-05-26
      • 2010-10-23
      相关资源
      最近更新 更多