Rails 在一段时间后产生“PGError:服务器意外关闭连接”的错误消息。

7
我有一个Rails应用程序的设置,如下所示:
  • Rails:3.0.5(在Apache代理下)运行于RHEL 5.6
  • Postgres:8.4,运行在Windows Server 2008上。这两个服务器在同一局域网内。
问题是,经过一段空闲时间后,当我向Rails应用程序发出新请求时,它会给我以下错误:
ActiveRecord::StatementInvalid (PGError: server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.

根据我的研究,Postgres会在一段时间后断开数据库连接。在此期间,从Rails方面来看,
  • 如果我向Rails发出请求(第一个请求),它将显示上述的连接错误
  • 如果我再次向Rails发出请求(第二个请求),Rails似乎会重新连接到Postgres并正常工作。
这意味着我总是会遇到第一个连接错误,然后所有操作都会恢复正常,这对我来说非常严重,因为我希望向客户交付无错误响应。
我查看了以下问题和答案,但它们似乎不适用于我的情况: 您有什么建议,以使我的应用程序免于数据库连接错误吗?谢谢。

我在使用Heroku和PostgreSQL时遇到了相同的错误。 - Salil
连接中断是很正常的事情,但 Rails 处理这种情况的方式并不优雅。请检查你所使用的数据库驱动程序(适配器)对 verify!active? 方法的实现;通常情况下,ActiveRecord::ConnectionAdapters::ConnectionPool 会在从池中获取连接之前给适配器一个重新连接任何过期连接的机会。你正在使用哪个 Postgres 的 gem? - vladr
3个回答

5

我们在Heroku上经常遇到这个问题。作为一个临时解决方案,以下是我们所做的。将以下代码放在您的ApplicationController中:

prepend_before_filter :confirm_connection
def confirm_connection
  c = ActiveRecord::Base.connection
  begin
    c.select_all "SELECT 1"
  rescue ActiveRecord::StatementInvalid
    ActiveRecord::Base.logger.warn "Reconnecting to database"
    c.reconnect!
  end
end

基本上,每次控制器命中时都会测试连接。可扩展性如何?不是很好。但它为我们解决了问题。


1
在 database.yml 文件中,你是否为连接设置了 reconnect: true 选项?例如:
production:
  adapter:   postgresql
  database:  myapp
  username:  deploy
  password:  password
  reconnect: true

我不确定具体的错误,但是如果没有这个选项,你需要自己处理一类预期的数据库错误。


0
我在上线期间遇到了这个错误。我刚刚打开了我的生产控制台,尝试连接PG数据库,并且成功了。
 RAILS_ENV=production rails c
 User.new

这样做后它就可以工作了。

希望能对某些人有所帮助;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接