2012-06-06 125 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(并失败)后加载。