5

ここでは自由回答形式の質問が少しあるので、最初に問題の概要を説明します。データ同期ジョブをキューからポップすることになっているResqueワーカーがいます。その理由は 2 つあります。Cron を使用する (そして Rails 環境の起動時間を何度も支払う) のが悪いことと、Github がうまく作成した代替キューです。彼らが Resque を発表したとき、彼らに対するかなり良いケースです。また、Redis の時系列機能は既にインフラストラクチャの大きな部分を占めており、TS データを RRDTool などにシャッフルしています...

ここに問題があります。典型的なジョブ間の間隔は 3 時間です (ただし、スタッフはいつでもジョブをスケジュールできます。そのため、キューが発生します)、PostgreSQL サーバーがなくなります。簡単に治すことができreconnect: true、対応する環境下での設定により、これが期待どおりに機能することが保証されると期待していました...を使用するアプリケーションでは機能しない場所いくつか 読みました. 当然のことながら、Resqueはワーカーを起動します...私が理解できない部分は、なぜ ActiveRecord の再接続がこれらの状況下で機能しないのかということです。reconnect: truefork()

reconnect!ActiveRecord でのMySQL アダプターPostgreSQL アダプターの実装が異なることに気付きましたが、いずれにしても ActiveRecord のreconnect: true構成は機能すると思います。

問題は十分に明確なようです。子プロセスが存在する場合、親によって作成されたファイルハンドルが閉じられます(したがって、データベースへの接続が切断されます)-ActiveRecordがそうしないような方法でファイルハンドルを閉じることは可能ですか接続が終了したことを認識しますか?

また、価値のあるものとして、Github で見つけたActiveRecord 対応の fork()もパスティとしてあります - テストしていませんが、動作すると思います (現在の Rails では試していません..)

私の質問はさらに、AR の自動再接続が機能しないのはなぜfork()ですか? (そして最近では、この問題を抱えているのは私だけではありません。Resque で PGSQL を使用しているせいだと思います!)

4

1 に答える 1

7

「なぜ再接続できないのか」に対する正確な答えではありませんが、初期化フェーズのどこかに次のコードを入れることが役立つと思います。


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 ドライバーは再接続機能を提供しません。

于 2011-04-17T22:55:46.630 に答える