2010-04-10 83 views
20

我的網站上運行Rails應用程序和resque工人在生產模式下運行,在Ubuntu 9.10,Rails的2.3.4,紅寶石EE 2010.01和PostgreSQL 8.4.2Rails的Resque工失敗,PGError:服務器關閉了連接意外

工人不斷提出錯誤:PGError:服務器意外關閉了連接。

我最好的猜測是,主要resque過程建立連接到數據庫(例如authlogic這樣做,當使用User.acts_as_authentic),同時加載rails應用程序類,並且該連接在fork()ed進程損壞(退出?) ,所以下一個分叉的孩子得到了一種破碎的全局ActiveRecord :: Base.connection

我可以重現非常類似的行爲,這個sample code模仿fork /處理resque worker。 (AFAIK,libpq的用戶建議重新創建分叉過程中的連接,否則它不安全)

但奇怪的是,當我使用pgbouncer或pgpool-II而不是直接pgsql連接時,不會出現此類錯誤。

因此,問題是我應該在哪裏以及如何挖掘以找出爲什麼它斷開連接並且正在使用連接池?還是合理的解決方法?

回答

12

當我創建Nestor時,我遇到了同樣的問題。解決方案是在分叉過程中重新建立連接。看到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

+6

謝謝,所以我簡單地加入了hook:Resque.after_fork = Proc.new {ActiveRecord :: Base。establish_connection} – 2010-04-10 10:10:48

+1

我可能會遇到類似的問題。你能告訴我你是如何以及在哪裏添加「鉤子」的? – 2011-03-23 12:04:38

+0

底部鏈接被破壞 – botbot 2013-07-30 01:06:34

9

您無法通過跨叉子的libpq引用( )(或者到一個新的線程),除非你的應用程序非常小心不要以衝突的方式使用它。 (比如,圍繞每一次嘗試使用它都需要一個互斥鎖,而且你絕不能關閉它)。這對於直接連接和使用pgbouncer都是一樣的。如果它在pgbouncer中有效,那純粹由於某種原因錯過了競爭條件,並且最終會失敗。

如果程序使用分叉,你必須創建在後叉連接

55

經過一些研究/試驗和錯誤。對於任何遇到同一問題的人。澄清什麼gc提到。

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" 

希望這可以幫助別人,因爲它爲我做了儘可能多的。

+6

你是一個紳士和學者,爲我省下了一些頭痛 – Jimmy 2011-07-28 03:25:39

+1

這是完美的! ...但是你可能想要移除'ENV ['QUEUE']'行,因爲這會將產生任何特定於隊列的工作人員設置爲'*' – nessur 2011-09-22 19:14:18

+0

my:setup任務應該在裏面:resque任務。 (不是一個resque:設置裏面:resque!)因爲這一開始這不適合我。我只是想告訴人們仔細檢查任務內容。 – scaryguy 2013-04-05 07:16:26

0

更改Apache的配置,並添加

PassengerSpawnMethod conservative 
0

我有這個問題與我所有的梅勒類的,我需要調用郵件方法中ActiveRecord::Base.verify_active_connections!,以確保作出的連接。

相關問題