2013-01-01 54 views
1

我現在在兩個應用程序中遇到了這個問題。 Heroku自己還沒有得到太多的幫助。Resque worker導致ActiveRecord :: StatementInvalid:PG :: Error:SSL SYSCALL錯誤:檢測到EOF

我使用:

  • 的Rails 3.2.9
  • Unicorn
  • 的Heroku,用Postgres的開發(免費)數據庫和OpenRedis微
  • 的MongoDB(用於存儲社交網絡狀態)
  • Resque
  • Resque-scheduler

使用我的本地Postgres和Redis數據庫運行時,一切正常。

下面是我在Heroku的日誌中的錯誤的一個例子:

2013-01-01T21:17:27+00:00 app[resque_worker.1]: Found job on #<Resque::Queue:0x00000006652920> 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: got: (Job{facebook} | FacebookRefresh | ["facebook_key"]) 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: Running before_fork hooks with [(Job{facebook} | FacebookRefresh | ["facebook_key"])] 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: Running after_fork hooks with [(Job{facebook} | FacebookRefresh | ["facebook_key"])] 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: resque-2.0.0.pre.1: Processing facebook since 1357075047 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: resque-2.0.0.pre.1: Forked 503 at 1357075047 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: Running before_perform hooks with [(Job{facebook} | FacebookRefresh | ["facebook_key"])] 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: :    SELECT a.attname, format_type(a.atttypid, a.atttypmod), 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    FROM pg_attribute a LEFT JOIN pg_attrdef d 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:     ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:      pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:). Retrying... 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: Performing FacebookRefresh caused an exception (PG::Error: SSL SYSCALL error: EOF detected 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    WHERE a.attrelid = '"facebook_accounts"'::regclass 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    ORDER BY a.attnum 
2013-01-01T21:17:27 
+00:00 app[resque_worker.1]:    AND a.attnum > 0 AND NOT a.attisdropped 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: :    SELECT a.attname, format_type(a.atttypid, a.atttypmod), 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    FROM pg_attribute a LEFT JOIN pg_attrdef d 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:     ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: (Job{facebook} | FacebookRefresh | ["facebook_key"]) failed: #<ActiveRecord::StatementInvalid: PG::Error: SSL SYSCALL error: EOF detected 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: > 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:      pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    AND a.attnum > 0 AND NOT a.attisdropped 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    WHERE a.attrelid = '"facebook_accounts"'::regclass 
2013-01-01T21:17:27+00:00 app[resque_worker.1]:    ORDER BY a.attnum 
2013-01-01T21:17:27+00:00 app[resque_worker.1]: Running before_fork hooks with [(Job{facebook} | FacebookRefresh | ["facebook_key"])] 

我試過這麼多before_hook和我的獨角獸的配置文件after_hook的事情,但他們都不來幫忙。

# What the timeout for killing busy workers is, in seconds 
timeout 60 

# Whether the app should be pre-loaded 
preload_app true 

# How many worker processes 
worker_processes 3 

before_fork do |server, worker| 
    # Replace with MongoDB or whatever 
    if defined?(ActiveRecord::Base) 
    ActiveRecord::Base.connection.disconnect! 
    Rails.logger.info('Disconnected from ActiveRecord') 
    end 

    # If you are using Redis but not Resque, change this 
    if defined?(Resque) 
    Resque.redis.quit 
    Rails.logger.info('Disconnected from Redis') 
    end 

    sleep 1 
end 

after_fork do |server, worker| 
    if defined?(ActiveRecord::Base) 
    ActiveRecord::Base.establish_connection 
    Rails.logger.info('Connected to ActiveRecord') 
    end 

    if defined?(Resque) 
    Resque.redis = ENV['OPENREDIS_URL'] || 'redis://localhost:6379' 
    Rails.logger.info('Connected to Redis') 
    end 
end 

而且我Procfile

web: bundle exec unicorn -c lib/unicorn/config.rb -p $PORT 
resque_scheduler: env bundle exec rake resque:scheduler 
resque_worker: env QUEUE=* bundle exec rake environment resque:work 

這麼一兩件事我想知道的是,我的resque_worker不使用麒麟配置可言的,因爲它在一個完全獨立的Heroku工人跑,我我不確定是否有任何方式可以知道這些東西。 web instnace和調度程序一樣好。它只是在每一次postgres會議上吹響的resque_worker。

我沒有做任何特別瘋狂的工作人員的數據庫調用。在一個例子可能是:

def queue_users_for_refresh 
    FacebookAccount.all.each do |x| 
    Resque.enqueue(FacebookAccountRefresh, x.username) 
    end 
end 

而另外一個版本(在FacebookAccountRefresh)是:

FacebookAccount.where(:username => user).first 
+1

@tibbion什麼呢resque與獨角獸ASFAIK做resque運行奧鋼聯rake任務,將有它自己的環境 – Viren

回答

5

這看起來像造成的跨進程共享的數據庫連接不正確的錯誤。發生這種情況時,Resque工作人員在分岔後不重新初始化數據庫連接。

你有一個Resque初始值設定項嗎?看起來你錯過了Resque工作者的after_fork指令來匹配你的Unicorn應用服務器工作者的指令。

添加/編輯您的Resque初始化文件(即:配置/初始化/ resque.rb):

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

該死的是,這是伎倆!非常感謝你。 – flsilva

+0

是否有替代monogid或mongodb的方法。 – codemilan

相關問題