Направляющие рабочие Resque перестали работать с PGError: сервер неожиданно закрыл соединение

У меня есть сайт, запускающий приложение направляющих и рискованных рабочих, работающих в производственном режиме, на Ubuntu 9.10, направляющие 2.3.4, рубиновые-ee 2010.01, PostgreSQL 8.4.2

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

Мое лучшее предположение - то, что основной рискованный процесс устанавливает соединение с дб (например, authlogic делает это, когда Пользователь acts_as_authentic использования), при загрузке классов приложения для направляющих, и то соединение становится поврежденным в ветвлении () процесс редактора (на выходе?), поэтому затем разветвленные дети получают вид поврежденного глобального ActiveRecord:: Base.connection

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

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

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

20
задан gc. 10 April 2010 в 00:27
поделиться

2 ответа

Когда я создал Нестора , у меня была такая же проблема. Решением было восстановить соединение в разветвленном процессе. См. Соответствующий код на 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

12
ответ дан 29 November 2019 в 22:35
поделиться

Вы не можете передать ссылку libpq через fork () (или в новый поток), если ваше приложение не позаботится о том, чтобы не использовать ее конфликтующими способами. (Например, мьютекс вокруг каждой попытки его использования, и вы никогда не должны его закрывать). То же самое и для прямого подключения, и для использования pgbouncer. Если это сработало в pgbouncer, это была чистая удача, потому что по какой-то причине не было состояния гонки, и в конечном итоге она сломается.

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

10
ответ дан 29 November 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: