2012-06-06 42 views
6

我遇到意外和重大的問題,試圖讓在Unicorn下運行的Rails應用連接到受密碼保護的Redis服務器。Resque沒有采用Redis配置設置

在命令行上使用bundle exec rails c production,我可以通過Resque.redis發出命令。但是,在Unicorn分支下,我的配置似乎正在丟失。

使用非密碼保護的Redis服務器Just Works。但是,我打算在Redis服務器所在的其他服務器上運行工作,因此我需要密碼保護。

我也成功地使用密碼保護(使用相同的技術),但使用乘客而不是獨角獸。

我有以下設置:

# config/resque.yml 

development: localhost:6379 
test: localhost:6379 
production: redis://user:[email protected]:6379 

# config/initializers/redis.rb 

rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..' 
rails_env = ENV['RAILS_ENV'] || 'development' 

$resque_config = YAML.load_file(rails_root + '/config/resque.yml') 
uri = URI.parse($resque_config[rails_env]) 
Resque.redis = Redis.new(host: uri.host, port: uri.port, password: uri.password) 

# unicorn.rb bootup file 

preload_app true 

before_fork do |server, worker| 
    Redis.current.quit 
end 

after_fork do |server, worker| 
    Redis.current.quit 
end 

回答

4

更新完全不同的想法基於@lmarlow's comment to a resque issue

我敢打賭,它打破了,無論你有Redis的〜> 3(我指的是紅寶石客戶端版本,而不是服務器版)。

在撰寫本文時,Resque需要Redis〜> 2,但並未在其gemspec中指定。因此,必須通過添加以下內容到Gemfile文件,以幫助它:

gem 'redis', '~>2' # until a new version of resque comes out 
gem 'resque' 

同時,確保捆綁器正在使用無處不在。否則,如果您的系統具有新版本的Redis Gem,它將被使用,並且Resque將像以前一樣失敗。

最後,化妝品筆記...你可以簡化配置來:

# config/initializers/redis.rb 
$resque_redis_url = uris_per_environment[rails_env] # note no URI.parse 
Resque.redis = $resque_redis_url 

然後

# unicorn.rb bootup file 
after_fork do |server, worker| 
    Resque.redis = $resque_redis_url 
end 
+0

我試過了(簡化,將配置保存在全局中),甚至在after_fork鉤子中將連接字符串硬編碼爲'Resque.redis =「redis:// user:[email protected]: 6379「'但唉,沒成功。 Resque Worker工作,Rails web應用程序無法使用它。如果我更改了端口,工作人員就會跟蹤這一點,而應用不會。 –

+0

如果您在生產中啓動導軌控制檯,「Resque.redis」的輸出是什麼? –

+1

從控制檯,一切都按預期工作,Resque.redis.info(例如)從服務器返回信息。如果我使用無效的密碼,我會得到一個「密碼錯誤」的樣式錯誤,所以我知道它在控制檯上正確連接。即使運行'Resque.redis.quit'後跟相同的'Resque.redis =「url」'命令也可以在控制檯上運行。 –

6

好,對誰可能是谷歌搜索這個問題別人着想,我已經解決了這個至少我自己

基本問題是調用代碼Redis.new其他地方,如在您的地理編碼器設置或獨角獸配置文件​​中。

只是確保每次調用時初始化Redis的你在適當的值 例如通過像

REDIS = Redis.connect(:url => ENV['REDISTOGO_URL']) 

無處不在,你永遠不應該有

Redis.new 

,因爲它會默認爲本地主機和默認端口

+0

謝謝,這是我的問題以及 –

+0

謝謝 - 這解決了它對我來說 –

2

這對我很有幫助:

來源:https://github.com/redis/redis-rb/blob/master/examples/unicorn/unicorn.rb

require "redis" 

worker_processes 3 

# If you set the connection to Redis *before* forking, 
# you will cause forks to share a file descriptor. 
# 
# This causes a concurrency problem by which one fork 
# can read or write to the socket while others are 
# performing other operations. 
# 
# Most likely you'll be getting ProtocolError exceptions 
# mentioning a wrong initial byte in the reply. 
# 
# Thus we need to connect to Redis after forking the 
# worker processes. 

after_fork do |server, worker| 
    Redis.current.quit 
end 
2

什麼工作對我來說是麒麟的配置在這裏:https://stackoverflow.com/a/14636024/18706

before_fork do |server, worker| 
    if defined?(Resque) 
    Resque.redis.quit 
    Rails.logger.info("Disconnected from Redis") 
    end 
end 

after_fork do |server, worker| 
    if defined?(Resque) 
    Resque.redis = REDIS_WORKER 
    Rails.logger.info("Connected to Redis") 
    end 
end 
0

我認爲這個問題是與Resque-網絡。它的配置文件,他們現在修復它。在0.0.11版本中,一提到它的評論,以及:https://github.com/resque/resque-web/blob/master/config/initializers/resque_config.rb#L3

早些時候,他們的文件看起來像這樣:https://github.com/resque/resque-web/blob/v0.0.9/config/initializers/resque_config.rb

而且,如果因任何原因,你不能升級,那麼寧可嘗試設置env變量RAILS_RESQUE_REDIS=<host>:<port>取而代之的是,在初始化器嘗試連接redis(並失敗)後加載。