2010-04-10 3 views
20

I 사이트 우분투 9.10에서 생산 모드에서 실행 레일 응용 프로그램과 resque 근로자를 실행은 8.4.2레일 Resque 근로자 PGError 실패 : 서버가 연결을 종료 예기치 않게

을, 2.3.4, 루비 EE 2010.01 레일 PostgreSQL을 가지고

근로자가 지속적으로 오류를 제기했습니다. PGError : 서버가 예기치 않게 연결을 종료했습니다.

rails app 클래스를로드하는 동안 master resque 프로세스가 db에 대한 연결을 설정합니다 (예 : authlogic이 User.acts_as_authentic을 사용할 때 해당 작업을 수행함). fork() 프로세스에서 해당 연결이 손상됩니다. 그래서 다음 forked 아이들은 깨진 글로벌 ActiveRecord :: Base.connection의 종류를 얻을

나는이 sample code와 유사한 행동을 재현 할 수있다. (AFAIK, libpq의 사용자는 어쨌든 fork 된 프로세스에서 연결을 다시 만들 것을 권장합니다. 그렇지 않으면 안전하지 않습니다)

그러나 이상한 점은 직접 pgsql 연결 대신 pgbouncer 또는 pgpool-II를 사용하면 이러한 오류가 나타나지 않는다는 것입니다 .

그래서 일반적인 연결에서 끊어진 이유와 연결 풀로 작업하는 이유를 어디에서 어떻게 확인해야합니까? 아니면 합리적인 해결 방법?

답변

12

을 만들었을 때 나는 같은 종류의 문제가있었습니다. 해결책은 분기 된 프로세스에서 연결을 다시 설정하는 것이 었습니다. Resque 코드에서 내 매우 제한된보기에서 http://github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#L162

에서 관련 코드를 참조하십시오, 나는 #establish_connection에 대한 호출이 바로 여기에 대해 수행해야합니다 생각 : https://github.com/resque/resque/blob/master/lib/resque/worker.rb#L123

+6

감사합니다. 그래서 나는 단순히 훅을 추가했습니다 : Resque.after_fork = Proc.new {ActiveRecord :: Base.establish_connection} –

+1

비슷한 문제가있을 수 있습니다. 어떻게 그리고 어디에서 "후크"를 추가했는지 말해 줄 수 있습니까? –

+0

하단 링크가 깨졌습니다 – botbot

9

당신은 포크에 걸쳐 libpq를 참조 (전달할 수 없습니다) (또는 새 스레드로), 응용 프로그램이 충돌이없는 방식으로 사용하지 않는 경우가 아니면 예외입니다. (모든 단일 시도를 사용할 때마다 뮤텍스를 사용하므로 닫지 않아야합니다.) 이것은 직접 연결과 pgbouncer를 사용하는 경우 모두 동일합니다. 그것이 pgbouncer에서 작동한다면, 그것은 어떤 이유에서든 경쟁 조건을 놓치게되는 순수 운이었고, 결국 깨질 것입니다.

프로그램이 분기 사용하는 경우, 당신은 포크 후 연결 를 작성해야합니다.

55

연구/시행 착오를 거친 후. 같은 문제를 겪고있는 사람에게. 언급 된 gc를 명확히하기. 예를 들어

/lib/tasks/resque.rake : 코드 위

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

가에 위치해야

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" 

희망이, 나를 위해했던만큼 사람을 도움이됩니다.

+6

당신은 신사이고 학자입니다. 확실히 두통을 덜어 줬습니다. – Jimmy

+1

이것은 완벽합니다! ...하지만'ENV [ 'QUEUE']'줄을 지우고 싶을 수도 있습니다. 그 이유는 큐 관련 작업자를'*'로 설정하여 낭비하기 때문입니다. – nessur

+0

my : 설치 작업이 내부 작업 : resque 작업. (resque가 아님 : setup : resque!) 처음에는 이것 때문에 나에게 도움이되지 못했습니다. 나는 단지 사람들에게 업무의 ​​부작용을 두 번 확인하라고 말하고 싶었다. – scaryguy

0

변경 아파치 구성 및

PassengerSpawnMethod conservative 
0

추가 나는 나의 메일러의 모든 클래스와 함께이 문제를했고 나는되었다 연결을 보장하기 위해 메일러 방법 내에서 ActiveRecord::Base.verify_active_connections!를 호출 할 필요가 있었다.