2012-06-06 15 views
6

Estoy teniendo problemas inesperados y significativos tratando de obtener una aplicación de Rails, ejecutándose en Unicorn, para conectarme a un servidor Redis protegido con contraseña.Resque no está recuperando la configuración de configuración de Redis

Utilizando bundle exec rails c production en la línea de comandos, puedo emitir comandos a través de Resque.redis. Sin embargo, parece que mi configuración se pierde cuando se bifurca en Unicornio.

Uso de un servidor Redis sin contraseña Just Works. Sin embargo, tengo la intención de ejecutar los trabajadores en otros servidores que el servidor donde vive Redis, por lo que necesito que esto esté protegido por contraseña.

También he tenido éxito en el uso de una contraseña protegida (usando la misma técnica) pero usando Passenger en lugar de Unicorn.

que tienen la siguiente configuración:

# 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 

.

Respuesta

4

ACTUALIZADO idea totalmente diferente basada en @lmarlow's comment to a resque issue.

Apuesto a que se rompe donde quiera que tenga Redis ~> 3 (me refiero a la versión de cliente de ruby, no a la versión de servidor).

En este momento, Resque necesita Redis ~> 2 pero no especifica eso en su gemspec. Por lo tanto usted tiene que ayudar a cabo mediante la adición de esto a su Gemfile:

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

Además, asegúrese de que bundler está siendo utilizado por todos lados. De lo contrario, si su sistema tiene una nueva versión de la gema Redis, se utilizará y Resque fallará como antes.

Por último, una nota cosmética ... que podría simplificar la configuración para:

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

y luego

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

He intentado esto (simplificar, almacenar la configuración en un global) e incluso he codificado la cadena de conexión en el hook after_fork como 'Resque.redis =" redis: // usuario: [email protected]: 6379 "' pero por desgracia, no hay éxito. Los trabajadores de Resque trabajan, la aplicación web Rails no puede usarlo. Si cambio el puerto, los trabajadores siguen esto, la aplicación no. –

+0

Si inicia una consola de rieles en producción, ¿cuál es el resultado de 'Resque.redis'? –

+1

Desde la consola, todo funciona exactamente como se esperaba, y Resque.redis.info (por ejemplo) devuelve información del servidor. Si utilizo una contraseña no válida, obtengo un error de "contraseña incorrecta", así sé que se está conectando correctamente en la consola. Incluso ejecutando 'Resque.redis.quit' seguido por el mismo comando' Resque.redis = "url" 'funciona desde la consola. –

6

Ok, por el bien de otras personas que podrían estar buscando en Google este problema, He resuelto esto por mí al menos

Problema básico es llamar a Redis.new otros lugares en el código, por ejemplo en su configuración de geocodificador o archivo de configuración de unicornio.

Sólo asegúrese de que cada vez que se llama a inicializar Redis se pasa en los valores apropiados por ejemplo algo así como

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

todas partes y nunca debe tener

Redis.new 

ya que será por defecto localhost y el puerto por defecto

+0

gracias, este fue mi problema también –

+0

gracias - esto lo resolvió para mí –

2

Esto fue útil para mí:

fuente: 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

Lo que funcionó para mí fue la config unicornio aquí: 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

Creo que el problema fue con Resque en la web. Su archivo de configuración, lo arreglaron ahora. En la versión 0.0.11, lo mencionan en un comentario así: https://github.com/resque/resque-web/blob/master/config/initializers/resque_config.rb#L3

Anteriormente, su archivo se veía así: https://github.com/resque/resque-web/blob/v0.0.9/config/initializers/resque_config.rb

Y, si por cualquier causa, no se puede actualizar, a continuación, en lugar tratar de establecer la variable de env RAILS_RESQUE_REDIS=<host>:<port> en su lugar, ya que los inicializadores se están cargando después de que intente conectar redis (y falla).

Cuestiones relacionadas