Рабочие Rails Razque потерпели неудачу с PGERROR: сервер неожиданно закрыл связь

StackOverflow https://stackoverflow.com/questions/2611747

Вопрос

У меня есть сайт Rights Rails Applications и Resque работников, работающих в режиме производства, на Ubuntu 9.10, Rails 2.3.4, Ruby-EE 2010.01, PostgreSQL 8.4.2

Рабочие постоянно подняли ошибки: PGERROR: сервер неожиданно закрыл связь.

Мое лучшее предположение состоит в том, что процесс Master Resque устанавливает подключение к БД (например, authLogic делает это при использовании user.acts_as_auteentic), во время загрузки классов приложений Rails, и что соединение становится поврежденным в процессе FORK () (на выходе?) Дети получают разбитый глобальный Activerecord :: Base.Connection

Я мог бы воспроизвести очень похожее поведение с этим образец кода Имитируя вилку / обработку в радостном работнике. (AFAIK, пользователи libpq рекомендовали воссоздать соединения в разветвленном процессе в любом случае, в противном случае это не безопасно)

Но странное, что когда я использую PGBouncer или PGPool-II вместо прямого PGSQL-соединения, такие ошибки не появляются.

Итак, вопрос в том, где я должен копать, чтобы узнать, почему он сломан для простого соединения и работает с соединительными пулами? Или разумный обходной путь?

Это было полезно?

Решение

Когда я создал Ненези, У меня была такая же проблема. Раствор должен был восстановить соединение в раздвоенном процессе. Смотрите соответствующий код в http://github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#l162.

От моего очень Ограниченный посмотрите на код Resque, я считаю, что звонок #establish_connection должен быть сделан прямо здесь: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#l123.

Другие советы

После проведения исследований / испытаний и ошибок. Для всех, кто наступает в ту же проблему. Уточнить, что упомянуто ГК.

Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }

Вышеуказанный код должен быть помещен в: /lib/tasks/resque.rake

Например:

require 'resque/tasks'

task "resque:setup" => :environment do
  ENV['QUEUE'] = '*'

  Resque.after_fork do |job|
    ActiveRecord::Base.establish_connection
  end

end

desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"

Надеюсь, это поможет кому-то, как это было для меня.

Вы не можете пройти ссылку в Libpq через вилку () (или на новую нить), если только ваше приложение не очень близко ухаживает о том, чтобы не использовать его в противоречивых способах. (Вроде, Mutex вокруг каждой попытки использовать его, и вы никогда не должны его закрывать). Это одинаковое для прямых соединений, так и для использования PGBouncer. Если он работал в PGBouncer, это была чистая удача во время пропустить состояние гонки по какой-то причине, и в конечном итоге сломается.

Если ваша программа использует Forking, вы должен Создайте соединение после разветвление.

Изменить конфигурацию Apache и добавить

PassengerSpawnMethod conservative

У меня был этот вопрос со всеми моими почтовыми классами, и мне нужно было позвонить ActiveRecord::Base.verify_active_connections! В рамках методов почтовых сообщений для обеспечения принятия соединения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top