这里有一个开放式问题,所以我先概述一下这个问题。我们有一个Resque工作者应该从队列中弹出数据同步作业,原因是双重的,使用Cron(并且支持Rails环境引导时间一遍又一遍)很糟糕,以及备用队列,当他们announced Resque时,Github对他们提出了相当好的理由。此外,Redis时间序列功能已经成为我们基础设施的重要组成部分,我们还将TS数据混合到RRDTool&等...
这是问题,工作间典型的三小时(但工作人员可以随时安排工作......因此队列),PostgreSQL服务器消失了。很容易治愈,我希望在相应的环境下设置reconnect: true
可以确保按预期工作..我在few places中读到reconnect: true
不会适用于使用fork()
的应用程序。自然Resque确实启动了它的工作人员...我不明白的部分是为什么ActiveRecord的重新连接在这些情况下无法工作?
我注意到reconnect!
MySQL Adapter和ActiveRecord中PostgreSQL Adapter的实现不同......但无论哪种方式,我都希望ActiveRecord reconnect: true
配置能够正常工作。
问题似乎很明显,当子进程存在时,它会关闭父进程创建的文件句柄(从而挂断与数据库的连接) - 是否有可能以ActiveRecord的方式关闭文件句柄无法识别连接已终止?
还有,值得一提的是ActiveRecord aware fork(),我能在Github上找到它作为一个牧师 - 它没有经过测试,但我认为它有效(没有用当前的Rails试过......)
我的问题更多,如果你fork()
为什么不能自动重新连接AR工作?(并且,后来 - 我不能成为唯一拥有此功能的人问题;我正在将它用于使用带有Resque的PGSQL!)
答案 0 :(得分:6)
虽然不完全是“为什么它不能重新连接”的答案,但我认为可以帮助你的是以下代码放在初始化阶段的某个地方:
Resque.after_fork do |job|
ActiveRecord::Base.connection.reconnect!
end
更新: 关于重新连接 - 似乎它只是MySQL的功能。 这是它在mysql适配器中的使用方式: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb#L848 如您所见,它使用底层驱动程序的重新连接功能。 https://github.com/kwatch/mysql-ruby/blob/master/ext/mysql.c#L923
另一方面,postgresql适配器对reconnect
选项没有任何作用,你可以看到https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
此外,PostgreSQL网站明确表示“使用开放的libpq连接分叉进程可能会导致不可预测的结果” - http://www.postgresql.org/docs/9.0/interactive/libpq-connect.html 而且很明显C驱动程序不提供任何重新连接功能。