15

私は rufus-scheduler を使用して、ActiveRecord オブジェクトでいくつかのさまざまなタスクを実行する多数の頻繁なジョブを実行しています。なんらかのネットワークまたは postgresql の問題が発生した場合、回復後でも、プロセスが再起動されるまで、すべてのスレッドが次のエラーをスローします。

ActiveRecord::ConnectionTimeoutError (5 秒以内にデータベース接続を取得できませんでした (5.000122687 秒待機)。最大プール サイズは現在 5 です。それを増やすことを検討してください。

このエラーは、postgres を再起動することで簡単に再現できます。プールサイズで(最大15)遊んでみましたが、運がありません。

これにより、接続が古い状態にあるだけであると信じるようになり、clear_stale_cached_connections!.

これを行うためのより信頼できるパターンはありますか?

渡されるブロックは単純な選択とアクティブ レコードの更新呼び出しであり、たまたま AR オブジェクトが何であるかが問題になります。

ルーファスの仕事:

scheduler.every '5s' do
  db do
    DataFeed.update  #standard AR select/update
  end
end

ラッパー:

  def db(&block)
    begin
      ActiveRecord::Base.connection_pool.clear_stale_cached_connections!
      #ActiveRecord::Base.establish_connection    # this didn't help either way
      yield block
    rescue Exception => e
      raise e
    ensure
      ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
      ActiveRecord::Base.clear_active_connections!
    end
  end
4

3 に答える 3

15

Rufus スケジューラは、ジョブごとに新しいスレッドを開始します。一方、ActiveRecord はスレッド間で接続を共有できないため、特定のスレッドに接続を割り当てる必要があります。

スレッドがまだ接続を持っていない場合、プールから接続を取得します。(プール内のすべての接続が使用中の場合、別のスレッドから接続が返されるまで待機します。最終的にはタイムアウトになり、ConnectionTimeoutError がスローされます)

作業が終わったら、それをプールに戻すのはあなたの責任です。Rails アプリでは、これは自動的に行われます。しかし、(rufus のように) 独自のスレッドを管理している場合は、これを自分で行う必要があります。

幸いなことに、このための API があります。コードを with_connection ブロック内に配置すると、プールから接続が取得され、完了時に解放されます。

ActiveRecord::Base.connection_pool.with_connection do
  #your code here
end

あなたの場合:

def db
  ActiveRecord::Base.connection_pool.with_connection do
    yield
  end
end

トリックを行う必要があります....

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html#method-i-with_connection

于 2013-10-15T12:00:32.903 に答える
-1

rufus-scheduler についてはよくわかりませんが、いくつかのアイデアがありました。

最初の問題は、データベース接続を適切にチェックアウトしない rufus-scheduler のバグである可能性があります。その場合、唯一の解決策は、既に行っているように古い接続を手動でクリアし、問題について rufus-scheduler の作成者に通知することです。

発生する可能性のあるもう 1 つの問題は、DataFeed 操作に非常に長い時間がかかることです。これは 5 秒ごとに実行されるため、Rails のデータベース接続が不足していますが、その可能性はほとんどありません。

于 2013-05-27T21:06:37.647 に答える