2012-06-06 6 views
6

Ho problemi inaspettati e significativi nel tentativo di ottenere un'app Rails, in esecuzione con Unicorn, per connettersi a un server Redis protetto da password.Resque non sta recuperando Impostazioni di configurazione Redis

Utilizzando bundle exec rails c production sulla riga di comando, è possibile inviare comandi tramite Resque.redis. Tuttavia, sembra che la mia configurazione si stia perdendo quando è forked sotto Unicorn.

Utilizzo di un server Redis protetto da password Funziona. Tuttavia, ho intenzione di eseguire lavoratori su altri server rispetto a dove risiede il server Redis, quindi ho bisogno che questo sia protetto da password.

Ho anche avuto successo nell'usare una password protetta (utilizzando la stessa tecnica) ma utilizzando Passeggero anziché Unicorno.

Ho la seguente configurazione:

# 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 

.

risposta

4

AGGIORNATO Idea completamente diversa basata su @lmarlow's comment to a resque issue.

Scommetto che si interrompe ovunque ci sia Redis ~> 3 (intendo la versione del client ruby, non quella del server).

Al momento della scrittura, Resque necessita di Redis ~> 2 ma non lo specifica nella sua gemspec. Pertanto è necessario aiutare fuori con l'aggiunta di questo alla vostra Gemfile:

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

Inoltre, assicurarsi che Bundler viene utilizzato in tutto il mondo. Altrimenti, se il tuo sistema ha una nuova versione della gemma Redis, si abituerà e Resque fallirà come prima.

Infine, una nota estetica ... si potrebbe semplificare la configurazione per:

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

e poi

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

Ho provato questo (semplificando, memorizzando la configurazione in un globale) e anche hardcoded la stringa di connessione nell'amo after_fork come 'Resque.redis =" redis: // user: [email protected]: 6379 "ma ahimè, nessun successo. Lavorare in resque, l'app web di Rails non riesce a usarlo. Se cambio la porta, i lavoratori la seguono, l'app no. –

+0

Se si avvia una console di rotaia in produzione, qual è l'output di 'Resque.redis'? –

+1

Dalla console, tutto funziona esattamente come previsto, e Resque.redis.info (per esempio) restituisce informazioni dal server. Se utilizzo una password non valida, ottengo un errore di stile "password errata", quindi so che si collega correttamente alla console. Anche l'esecuzione di 'Resque.redis.quit' seguita dallo stesso comando' Resque.redis = "url" 'funziona dalla console. –

6

Ok, per il bene di altre persone che potrebbero essere googling questo problema, Ho risolto questo per me almeno

problema di base sta chiamando Redis.new altri posti nel codice, ad esempio nella configurazione del geocoder o nel file di configurazione di unicorno.

assicurati che ogni volta che chiami Initialize Redis passi i valori appropriati ad es.qualcosa come

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

ovunque e non si dovrebbe mai avere

Redis.new 

come questo verrà impostato a localhost e la porta di default

+0

grazie, questo era il mio problema pure –

+0

grazie - questo lo ha risolto per me –

2

Questo è stato utile per me:

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

Che cosa ha funzionato per me era la configurazione unicorno qui: 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

Credo che il problema era con Resque-web. Il suo file di configurazione, lo hanno risolto ora. Nella versione 0.0.11, accennano in un commento così: https://github.com/resque/resque-web/blob/master/config/initializers/resque_config.rb#L3

In precedenza, proprio file si presentava così: https://github.com/resque/resque-web/blob/v0.0.9/config/initializers/resque_config.rb

E, se a causa di qualsiasi causa, non è possibile aggiornare, quindi piuttosto cercare di impostare la variabile ENV RAILS_RESQUE_REDIS=<host>:<port> invece, mentre gli inizializzatori si caricano dopo che tenta di connettersi redis (e fallisce).