Vinicius Baggio Fuentes

  1. Software Engineer — Medium
  2. Autor — Casa do Código
  3. Compre já!
29 Mar 2012 — Careful With That Hax Eugene

Careful With That Hax, Eugene

(Esta é uma brincadeira com o nome da música "Careful with that axe, Eugene", do Pink Floyd)

Dificilmente temos um site hoje em dia em que não precisamos usar jobs em background. Para Rails, o Resque é uma das soluções mais populares.

O resque vem com uma ferramenta bem elegante para monitoração das filas:

Resque-web

Essa ferramenta é excelente para monitorar e depurar os jobs executando no site atualmente. Por isso é bastante comum colocarmos o resque-web em algum ponto tal que possamos acessar de qualquer lugar para gerenciar as filas.

Jeito 1: servidor embutido do resque-web

O jeito mais simples de colocar esse monitor no ar é executando o resque-web manualmente e protegê-lo via HTTP Basic auth.

Dessa forma, basicamente basta rodar o resque-web:

resque-web config/resque-web.rb

E, em seguida, protegê-lo, no nginx podemos fazer:

upstream resque {
  server 127.0.0.1:5678;
}

server {
  server_name resque.example.com;

  location / {
    auth_basic "Restricted";
    auth_basic_user_file /opt/nginx/conf/htpasswd;
    proxy_pass http://resque;
  }
}

Assim, ao acessar resque.example.com, você será apresentado por uma tela de autenticação comum HTTP (lógico que você precisa gerar o htpasswd).

Rá! Pegadinha do Mallandro! Ié ié!

Tem um problema nessa história. Por padrão, o resque-web faz bind no host 0.0.0.0. Isso significa que requisições por qualquer interface de rede irá responder. Assim, se você digitar o IP e a porta diretamente, o nginx não irá interceptar a requisição e irá cair no resque-web, que é um grande risco, já que você pode deletar as filas e ver informações talvez sensíveis.

A solução é bem simples. Basta você iniciar o resque-web com o comando para fazer o bind no host 127.0.0.1. Isso fará com que o vegas (servidor HTTP que o resque-web) receba apenas conexões via loopback, ou seja, apenas de servidores locais (tudo isso quem faz é o esperto do kernel do Linux).

resque-web -o 127.0.0.1 config/resque-web.rb

Ou seja, se você for ao endereço de IP, por exemplo 200.100.123.456:5678, a requisição jamais irá chegar no resque-web pois o servidor vegas não estará ouvindo requisições da interface de rede exposta à internet, mas o nginx será capaz de comunicar-se pois estão em contato via loopback. Legal né?

Jeito 2: resque-web dentro do Rails

Outra maneira é embutir o resque-web dentro da sua aplicação Rails. O problema dessa forma é que você irá ocupar preciosos recursos de sua web app com painel de administração. Ou talvez você nem queira ter sua app rails rodando no mesmo servidor em que o resque estiver executando.

A grande vantagem dessa forma é que você pode usar de regras de aplicação dentro do Rails. O resque-web não deixa de ser uma Rack app, podendo ser montada facilmente dentro do Rails:

Coolapp::Application.routes.draw do
  mount Resque::Server.new, :at => "/resque"
end

O mais legal de tudo é que se você usar o Devise, você pode usar o sistema de login da sua própria aplicação para permitir apenas admins a entrarem no resque-web:

Coolapp::Application.routes.draw do
  authenticate :admin_user do
    mount Resque::Server.new, :at => "/resque"
  end
end

Um único porém dessa solução é que, ao tentar entrar deslogado, rola uma redireção infinita, mas deve ser alguma coisa que eu fiz de errado, que no meu caso deve relacionar-se com o ActiveAdmin.

Essa versão também tem outro problema. Em produção, quem serve os arquivos estáticos é o nginx ou Apache. Dessa forma, ao fazer deploy, você tem que fazer um symlink dos estáticos dentro da gem para o seu public, que pode ser um pouco chato.

Leia também

blog comments powered by Disqus