Resque没有获取Redis配置设置

时间:2012-06-06 20:59:11

标签: ruby-on-rails redis resque unicorn

我在尝试获取在Unicorn下运行的Rails应用程序以连接到受密码保护的Redis服务器时遇到意外和重大问题。

在命令行上使用bundle exec rails c production,我可以通过Resque.redis发出命令。但是,当它在Unicorn下分叉时,我的配置似乎正在丢失。

使用非密码保护的Redis服务器Just Works。但是,我打算在其他服务器上运行工作程序,而不是Redis服务器所在的服务器,因此我需要密码保护。

我也成功使用密码保护(使用相同的技术)但使用Passenger而不是Unicorn。

我有以下设置:

# config/resque.yml

development: localhost:6379
test: localhost:6379
production: redis://user:PASSWORD@oak.isc.org: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

5 个答案:

答案 0 :(得分:6)

好的,为了其他可能在谷歌上搜索这个问题的人,我至少为自己解决了这个问题

基本问题是在代码中调用Redis.new其他地方,例如。在您的地理编码器设置或独角兽配置文件​​中。

只需确保每次调用初始化Redis时都传递适当的值 例如

之类的东西
REDIS = Redis.connect(:url =>  ENV['REDISTOGO_URL'])
无处不在,你永远不应该

Redis.new 

因为它将默认为localhost和默认端口

答案 1 :(得分:5)

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

我打赌它会在你拥有Redis的地方打破〜> 3(我的意思是ruby客户端版本,而不是服务器版本)。

在撰写本文时,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

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

我认为问题出在Resque-web上。它的配置文件,他们现在修复它。在版本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(并且失败)之后加载。