Rails Reaper无法正常工作

时间:2016-04-14 09:34:02

标签: ruby-on-rails postgresql ruby-on-rails-4 activerecord

根据API文档,rails reaper用于查找和恢复死线程的连接。收割机基于reaping_频率运行。

我遇到的情况是数据库连接数超过指定限制且连接处于空闲状态但收割者没有重置这些连接。我尝试手动运行收割机,但似乎没有任何效果。

reaper = ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper.new(ActiveRecord::Base.connection, 10)
reaper.run

使用

验证它没有任何效果
ActiveRecord::Base.connection.execute("SELECT * FROM pg_stat_activity WHERE pid <> pg_backend_pid()")
PgHero.total_connections

这是ActiveRecord中收割机的错误还是不适合这样工作?如果是这样的话,如何选择编写自定义收割机来恢复死连接? pg gem用于连接postgres db。占用连接的查询是:

  

显示交易隔离级别

Rails版本:4.2.3

pg gem version:0.17.1

Postgres版本:9.4.6

Rails应用服务器:Puma

3 个答案:

答案 0 :(得分:5)

首先注意几点:

  • 可能不是“吃掉”你的数据库连接的SHOW TRANSACTION ISOLATION LEVEL查询。 pg_stat_activity视图只显示在每个连接上执行的有效或 last query 。因此,统计数据中更重要的信息就是打开了太多的连接。

  • ConnectionPool::Reaper释放数据库连接,但仅从dead threads 释放,即已停止或意外终止的连接。但它不会影响连接活动或休眠线程。收割者不适合你的事实IMO只是意味着那些线程可能正在睡觉,而不是死亡。

现在,超出最大值可能有很多原因。允许在数据库服务器上建立连接:

  • 您可能太多线程同时检查了与db的连接ConnectionPool通常为每个线程保留一个与db的连接,最多为pool中配置的database.yml大小。因此,如果您的池大小相当大并且您有许多线程,则可以超过最大值。数据库连接。例如,puma最多可创建16 threads by default

  • 每个rails进程都定义了自己的连接池。因此,如果您的池大小定义为10并且您有10个rails进程,则与db的连接可以提升到{{ 1}}连接。 Puma服务器允许运行multiple workers(这是独立的进程),因此你可能有太多的puma工作者在运行。

  • 同样的逻辑适用于所有后台进程和线程。例如,Sidekiq默认情况下为后台作业创建最多25个线程。因此,如果您在代码中使用线程或在内部使用线程的任何gem,例如对于后台作业功能,您必须了解它们的精确设置,以便不超过最大连接数。

  • 您可能会遇到数据库连接泄漏。当使用10 * 10 = 100(应用程序预加载)时,Puma服务器需要特殊设置,以便不泄漏数据库连接。这记录在例如herehere

答案 1 :(得分:0)

Mongrel / Passenger时代,在构建Rack之前,运行Rails应用程序的唯一方法是使用Sub sbHidingUnHideRows() If Rows("22:25").EntireRow.Hidden = True Then Rows("22:25").EntireRow.Hidden = False Else Rows("22:25").EntireRow.Hidden = True End If End Sub 脚本/ reaper文件用于启动/停止Rails进程。

默认情况下,Capistrano尝试启动运行reaper脚本的新Rails进程。您应该自定义默认行为。请参考, (https://simonecarletti.com/blog/2008/12/capistrano-deploy-recipe-with-passenger-mod_rails-taste/

Capistrano将在部署时正常重启您的Passenger实例。

答案 2 :(得分:-1)

请将以下代码添加到config/deploy.rb

deploy.task :restart, :roles => :app do
  run "touch #{current_path}/tmp/restart.txt"
end

案例2如果使用Capistrano(只删除脚本/进程目录):

默认情况下,Capistrano尝试启动运行reaper脚本的新Rails进程。您应该自定义默认行为。

假设您使用Passenger运行Rails应用程序(mod_rails),请安装以下Capistrano + Passenger(mod_rails)配方,Capistrano将在部署时正常重启您的Passenger实例。