2012-06-06 9 views
6

Mam nieoczekiwane i znaczące problemy z próbą pobrania aplikacji Railsowej działającej pod Unicorn, aby połączyć się z chronionym hasłem serwerem Redis.Resque nie odbiera ustawień konfiguracyjnych Redis

Przy użyciu linii poleceń mogę wydawać polecenia przez Resque.redis. Wygląda jednak na to, że moja konfiguracja jest tracona, gdy rozwidla się pod Unicornem.

Używanie serwera Redis bez ochrony hasłem Just Works. Jednak zamierzam uruchamiać pracowników na innych serwerach niż serwer Redis, więc potrzebuję tego do ochrony hasłem.

Udało mi się również użyć hasła chronionego (przy użyciu tej samej techniki), ale używając Pasażera zamiast Jednorożca.

Mam następującą konfigurację:

# 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 

.

Odpowiedz

4

ZAKTUALIZOWANY Całkowicie inny pomysł oparty na @lmarlow's comment to a resque issue.

Założę się, że zepsuje się gdziekolwiek masz Redis ~ 3 (mam na myśli wersję klienta ruby, a nie wersję serwerową).

Od tego momentu Resque wymaga Redis ~> 2, ale nie określa tego w swoim gemspec. Dlatego musisz pomóc, dodając to do swojej Gemfile:

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

Upewnij się również, że bundler jest używany wszędzie. W przeciwnym razie, jeśli twój system ma nową wersję klejnotu Redis, zostanie użyty, a Resque nie powiedzie się jak poprzednio.

Wreszcie uwaga kosmetyk ... można uprościć config:

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

a następnie

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

Próbowałem tego (uproszczenie, przechowywanie konfiguracji w globalnej), a nawet zakodowałem ciąg połączenia w haku after_fork jako 'Resque.redis =" redis: // user: [email protected]: 6379 "' ale niestety, bez powodzenia. Pracownicy Resque pracują, aplikacja internetowa Railsy nie używają jej. Jeśli zmienię port, pracownicy śledzą to, aplikacja nie. –

+0

Jeśli uruchomisz konsolę szynową podczas produkcji, jaki jest wynik działania 'Resque.redis'? –

+1

Z konsoli wszystko działa zgodnie z oczekiwaniami, a Resque.redis.info (na przykład) zwraca informacje z serwera. Jeśli użyję nieprawidłowego hasła, otrzymam błąd stylu "hasło jest złe", więc wiem, że poprawnie łączy się z konsolą. Nawet uruchomienie 'Resque.redis.quit', po którym następuje to samo polecenie' Resque.redis = "url" 'działa z poziomu konsoli. –

6

Ok, dla dobra innych ludzi, którzy mogą być Googling ten problem, Rozwiązałem to dla siebie co najmniej

Podstawowym problemem jest wywoływanie Redis.new innych miejsc w kodzie, np. w konfiguracji geocodera lub pliku konfiguracyjnym jednorożca.

po prostu upewnij się, że za każdym razem, gdy wywoływana jest inicjalizacja Redis, przekazujesz odpowiednie wartości np.coś

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

wszędzie i nigdy nie powinno mieć

Redis.new 

jak będzie domyślnie localhost i port domyślny

+0

dziękuję, to był mój problem, –

+0

dzięki - rozwiązało to dla mnie –

2

To było przydatne do mnie:

źródło: 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

Co pracował dla mnie był jednorożec config tutaj: 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

Myślę, że problem był z Resque-web. Jego plik konfiguracyjny, naprawili go teraz. W wersji 0.0.11, wspominają go w komentarzu, a także: https://github.com/resque/resque-web/blob/master/config/initializers/resque_config.rb#L3

Wcześniej ich plik wyglądał następująco: https://github.com/resque/resque-web/blob/v0.0.9/config/initializers/resque_config.rb

A jeśli z jakichkolwiek powodów nie można uaktualnić, a raczej starają się ustawić zmienna env RAILS_RESQUE_REDIS=<host>:<port> zamiast tego, gdy inicjalizatory ładują się po tym, jak próbuje połączyć się z redis (i kończy się niepowodzeniem).

Powiązane problemy