Opções do servidor Ruby on Rails [fechado]

578

Todo o problema de configurar um servidor de desenvolvimento para o meu aplicativo Ruby on Rails me confunde. Existem WEBrick, Mongrel, Passenger, Apache, Nginx e muitos mais, tenho certeza, e eu realmente não entendo os diferentes papéis que eles desempenham.

Comecei usando o WEBrick e agora uso o Mongrel para desenvolvimento. Esses servidores são independentes ou ficam na frente do Apache?

Eu li sobre o Passenger e realmente não entendo o que é, o site diz "facilita a implantação de aplicativos da web Ruby", substitui o Mongrel? É como o Capistrano, que também implementa aplicativos da web?

Tendo em mente que gostaria de testar o SSL, e acredito que isso não é suportado pelo mongrel, qual é a melhor configuração do servidor de desenvolvimento?

obrigado

pingu
fonte
2
Você já assistiu o screencast do Phusion Passenger? Descreve praticamente em 5 minutos tudo o que é necessário para colocar seu aplicativo Rails online.
Hongli
27
Para uma pergunta não construtiva, isso certamente recebeu muitos votos positivos, e também a resposta.
Teemu Leisti 13/11
32
Eu sei que esta pergunta quebra as regras do SO, mas me pergunto se muitos usuários acham essa pergunta útil. Talvez seja hora de modificar algumas regras?
Hardik

Respostas:

1264

A palavra "implantação" pode ter dois significados, dependendo do contexto. Você também está confundindo as funções do Apache / Nginx com as funções de outros componentes.

Nota histórica: Este artigo foi originalmente escrito em 6 de novembro de 2010, quando o ecossistema de servidores de aplicativos Ruby era limitado. Atualizei este artigo em 15 de março de 2013 com todas as atualizações mais recentes no ecossistema.

Disclaimer : Eu sou um dos autores do Phusion Passenger, um dos servidores de aplicativos.

Apache vs Nginx

Ambos são servidores web. Eles podem servir arquivos estáticos, mas - com os módulos corretos - também podem servir aplicativos dinâmicos da Web, como os escritos em PHP. O Apache é mais popular e possui mais recursos, o Nginx é menor e mais rápido e possui menos recursos.

Nem o Apache nem o Nginx podem fornecer aplicativos da Web Ruby prontos para o uso. Para isso, é necessário usar o Apache / Nginx em combinação com algum tipo de complemento, descrito mais adiante.

O Apache e o Nginx também podem atuar como proxies reversos, o que significa que eles podem receber uma solicitação HTTP recebida e encaminhá-la para outro servidor, que também fala HTTP. Quando esse servidor responder com uma resposta HTTP, o Apache / Nginx encaminhará a resposta de volta ao cliente; Você aprenderá mais tarde por que isso é relevante.

Mongrel e outros servidores de aplicativos de produção vs WEBrick

O Mongrel é um "servidor de aplicativos" do Ruby: Em termos concretos, isso significa que o Mongrel é um aplicativo que:

  1. Carrega seu aplicativo Ruby dentro de seu próprio espaço de processo.
  2. Configura um soquete TCP, permitindo que ele se comunique com o mundo exterior (por exemplo, a Internet). Mongrel escuta solicitações HTTP neste soquete e passa os dados da solicitação para o aplicativo Web Ruby.
  3. O aplicativo da web Ruby retorna um objeto, que descreve como deve ser a resposta HTTP, e Mongrel cuida da conversão para uma resposta HTTP real (os bytes reais) e a envia de volta pelo soquete.

No entanto, Mongrel é bastante datado, hoje em dia não é mais mantido. Os servidores de aplicativos alternativos mais recentes são:

  • Phusion Passenger
  • Unicórnio
  • Fino
  • Puma
  • Trinidad (apenas JRuby)
  • TorqueBox (apenas JRuby)

Vou abordá-los mais tarde e descrever como eles diferem um do outro e de Mongrel.

O WEBrick faz a mesma coisa que Mongrel, mas as diferenças são:

  • O WEBrick não é adequado para produção, ao contrário de tudo o que mencionei antes. O WEBrick é escrito inteiramente em Ruby. O Mongrel (e a maioria dos outros servidores de aplicativos Ruby) faz parte do Ruby e parte C (Principalmente Ruby), mas seu analisador HTTP é escrito em C para desempenho.
  • O WEBrick é mais lento e menos robusto. Possui alguns vazamentos de memória conhecidos e alguns problemas conhecidos de análise de HTTP.
  • O WEBrick geralmente é usado apenas como servidor padrão durante o desenvolvimento porque o WEBrick está incluído no Ruby por padrão. O Mongrel e outros servidores de aplicativos precisam ser instalados separadamente. Não é recomendável usar o WEBrick em ambientes de produção, embora, por algum motivo, a Heroku tenha escolhido o WEBrick como servidor padrão. Eles estavam usando o Thin antes, então eu não tenho idéia do porquê eles mudaram para o WEBrick.

O servidor de aplicativos e o mundo

Todos os servidores de aplicativos Ruby atuais falam HTTP, no entanto, alguns podem estar diretamente expostos à Internet na porta 80, enquanto outros não.

  • Servidores de aplicativos que podem ser diretamente expostos à Internet: Phusion Passenger, Rainbows
  • Servidores de aplicativos que não podem ser diretamente expostos à Internet: Mongrel, Unicorn, Thin, Puma. Esses servidores de aplicativos devem ser colocados atrás de um servidor Web proxy reverso, como Apache e Nginx.
  • Eu não sei o suficiente sobre Trinidad e TorqueBox, então eu os omiti.

Por que alguns servidores de aplicativos devem ser colocados atrás de um proxy reverso?

  • Alguns servidores de aplicativos podem lidar apenas com 1 solicitação simultaneamente, por processo. Se você deseja lidar com 2 solicitações simultaneamente, precisa executar várias instâncias do servidor de aplicativos, cada uma servindo o mesmo aplicativo Ruby. Esse conjunto de processos do servidor de aplicativos é chamado de cluster de servidores de aplicativos (daí o nome Mongrel Cluster, Thin Cluster etc.). Você deve configurar o Apache ou o Nginx para reverter o proxy para este cluster. O Apache / Nginx cuidará da distribuição de solicitações entre as instâncias no cluster (Mais sobre isso na seção "Modelos de simultaneidade de E / S").
  • O servidor da Web pode armazenar pedidos e respostas em buffer, protegendo o servidor de aplicativos de "clientes lentos" - clientes HTTP que não enviam ou aceitam dados muito rapidamente. Você não deseja que o servidor de aplicativos não faça nada enquanto aguarda que o cliente envie a solicitação completa ou receba a resposta completa, pois durante esse período o servidor de aplicativos poderá não conseguir fazer mais nada. O Apache e o Nginx são muito bons em fazer muitas coisas ao mesmo tempo porque são multithread ou evented.
  • A maioria dos servidores de aplicativos pode servir arquivos estáticos, mas não é particularmente boa nisso. Apache e Nginx podem fazê-lo mais rapidamente.
  • As pessoas normalmente configuram o Apache / Nginx para veicular arquivos estáticos diretamente, mas encaminhar solicitações que não correspondem aos arquivos estáticos para o servidor de aplicativos é uma boa prática de segurança. O Apache e o Nginx são muito maduros e podem proteger o servidor de aplicativos de solicitações corrompidas (talvez maliciosamente).

Por que alguns servidores de aplicativos podem ser diretamente expostos à Internet?

  • O Phusion Passenger é um animal muito diferente de todos os outros servidores de aplicativos. Uma de suas características únicas é que ele se integra ao servidor da web.
  • O autor do Rainbows declarou publicamente que é seguro expô-lo diretamente à Internet. O autor tem certeza de que não há vulnerabilidades no analisador HTTP (e similares). Ainda assim, o autor não oferece garantia e diz que o uso é por conta e risco.

Servidores de aplicativos comparados

Nesta seção, compararei a maioria dos servidores de aplicativos que mencionei, mas não o Phusion Passenger. O Phusion Passenger é um animal tão diferente do resto que eu lhe dei uma seção dedicada. Também omiti o Trinidad e o TorqueBox porque não os conheço o suficiente, mas eles são relevantes apenas se você usar o JRuby.

  • Mongrel era um osso bastante nu. Como mencionado anteriormente, o Mongrel é um multiprocesso puramente de thread único, portanto, é útil apenas em um cluster. Não há monitoramento de processo: se um processo no cluster travar (por exemplo, devido a um erro no aplicativo), ele precisará ser reiniciado manualmente. As pessoas tendem a usar ferramentas externas de monitoramento de processos, como Monit e Deus.
  • Unicorn é um garfo de vira-lata. Ele suporta monitoramento limitado do processo: se um processo falha, é reiniciado automaticamente pelo processo mestre. Ele pode fazer com que todos os processos escutem em um único soquete compartilhado, em vez de um soquete separado para cada processo. Isso simplifica a configuração do proxy reverso. Como Mongrel, é um multiprocesso puramente de thread único.
  • O Thin usa o modelo de E / S de eventos utilizando a biblioteca EventMachine. Além de usar o analisador HTTP Mongrel, ele não é baseado no Mongrel de forma alguma. Seu modo de cluster não possui monitoramento de processo, portanto é necessário monitorar falhas etc. Não há soquete compartilhado como o Unicorn, portanto cada processo escuta em seu próprio soquete. Em teoria, o modelo de E / S do Thin permite alta simultaneidade, mas nas situações mais práticas para as quais o Thin é usado, um processo do Thin pode lidar apenas com 1 solicitação simultânea, portanto, você ainda precisa de um cluster. Mais sobre essa propriedade peculiar na seção "Modelos de simultaneidade de E / S".
  • A Puma também foi bifurcada da Mongrel, mas, ao contrário do Unicorn, a Puma foi projetada para ser puramente multiencadeada. Portanto, atualmente não há suporte de cluster interno. Você precisa tomar cuidado especial para garantir a utilização de vários núcleos (mais sobre isso na seção "Modelos de simultaneidade de E / S").
  • O Rainbows suporta vários modelos de simultaneidade através do uso de diferentes bibliotecas.

Phusion Passenger

O Phusion Passenger funciona de maneira muito diferente de todos os outros. O Phusion Passenger se integra diretamente ao Apache ou Nginx e, portanto, pode ser comparado ao mod_php do Apache. Assim como o mod_php permite que o Apache atenda a aplicativos PHP, quase que magicamente, o Phusion Passenger permite que o Apache (e também o Nginx!) Atenda a aplicativos Ruby, quase que magicamente. O objetivo do Phusion Passenger é tornar tudo o Just Work (tm) com o mínimo de problemas possível.

Em vez de iniciar um processo ou cluster para seu aplicativo e configurar o Apache / Nginx para servir arquivos estáticos e / ou solicitações de proxy reverso para o processo / cluster com o Phusion Passenger, você só precisa:

  1. Você edita o arquivo de configuração do servidor web e especifica o local do diretório 'público' do seu aplicativo Ruby.
  2. Não há etapa 2.

Toda a configuração é feita no arquivo de configuração do servidor da web. O Phusion Passenger automatiza praticamente tudo. Não há necessidade de iniciar um cluster e gerenciar processos. Iniciando / parando processos, reiniciando-os quando eles travam, etc. - todos automatizados. Comparado a outros servidores de aplicativos, o Phusion Passenger possui muito menos peças móveis. Essa facilidade de uso é um dos principais motivos pelos quais as pessoas usam o Phusion Passenger.

Também diferente de outros servidores de aplicativos, o Phusion Passenger é escrito principalmente em C ++, tornando-o muito rápido.

Há também uma variante Enterprise do Phusion Passenger com ainda mais recursos, como reinicializações automáticas, suporte a multithreading, resistência a erros de implantação, etc.

Pelas razões acima, atualmente, o Phusion Passenger é o servidor de aplicativos Ruby mais popular, com mais de 150.000 sites, incluindo grandes como New York Times, Pixar, Airbnb, etc.

Phusion Passenger vs outros servidores de aplicativos

O Phusion Passenger oferece muito mais recursos e muitas vantagens sobre outros servidores de aplicativos, como:

  • Ajustar dinamicamente o número de processos com base no tráfego. Executamos uma tonelada de aplicativos Rails em nosso servidor com recursos limitados que não são voltados para o público e que as pessoas em nossa organização usam apenas no máximo algumas vezes por dia. Coisas como Gitlab, Redmine, etc. O Phusion Passenger pode diminuir esses processos quando não são usados ​​e aumentá-los quando são usados, permitindo que mais recursos estejam disponíveis para aplicativos mais importantes. Com outros servidores de aplicativos, todos os seus processos são ativados o tempo todo.
  • Alguns servidores de aplicativos não são bons em determinadas cargas de trabalho, por design. Por exemplo, o Unicorn foi desenvolvido apenas para solicitações de execução rápida: consulte a seção do site do unicórnio "Pior em alguns casos".

As cargas de trabalho nas quais o Unicorn não é bom são:

  • Cargas de trabalho de streaming (por exemplo, streaming ao vivo do Rails 4 ou streaming de modelos do Rails 4).
  • Cargas de trabalho nas quais o aplicativo executa chamadas da API HTTP.

O modelo de E / S híbrido no Phusion Passenger Enterprise 4 ou posterior o torna uma excelente opção para esse tipo de carga de trabalho.

  • Outros servidores de aplicativos exigem que o usuário execute pelo menos uma instância por aplicativo. Por outro lado, o Phusion Passenger suporta vários aplicativos em uma única instância. Isso reduz bastante a sobrecarga da administração.
  • Troca automática de usuário, um recurso de segurança conveniente.
  • O Phusion Passenger suporta muitos MRI Ruby, JRuby e Rubinius. Mongrel, Unicorn e Thin suportam apenas ressonância magnética. A Puma também suporta todos os 3.
  • O Phusion Passenger realmente suporta mais do que apenas Ruby! Ele também suporta Python WSGI, para que, por exemplo, também execute aplicativos Django e Flask. De fato, o Phusion Passenger está se movendo na direção de se tornar um servidor poliglota. Suporte para Node.js na lista de tarefas.
  • Coleta de lixo fora da banda. O Phusion Passenger pode executar o coletor de lixo Ruby fora do ciclo normal de solicitação / resposta, potencialmente reduzindo o tempo de solicitação em centenas de milissegundos. O Unicorn também possui um recurso semelhante, mas a versão do Phusion Passenger é mais flexível porque 1) não se limita ao GC e pode ser usada para trabalhos arbitrários. 2) A versão do Phusion Passenger funciona bem com aplicativos multithread, enquanto a do Unicorn não.
  • Reinicialização automática do rolamento. A reinicialização contínua no Unicorn e em outros servidores exige algum trabalho de script. O Phusion Passenger Enterprise automatiza completamente esse caminho para você.

Existem mais recursos e vantagens, mas a lista é realmente longa. Você deve consultar o manual abrangente do Phusion Passenger ( versão Apache , versão Nginx ) ou o site do Phusion Passenger para obter informações.

Modelos de simultaneidade de E / S

  • Multi-processo de thread único. Tradicionalmente, esse é o modelo de E / S mais popular para servidores de aplicativos Ruby, em parte porque o suporte a multithreading no ecossistema Ruby era muito ruim. Cada processo pode lidar com exatamente 1 solicitação por vez. A carga do servidor da web se equilibra entre processos. Esse modelo é muito robusto e há poucas chances de o programador apresentar erros de simultaneidade. No entanto, sua simultaneidade de E / S é extremamente limitada (limitada pelo número de processos). Este modelo é muito adequado para cargas de trabalho rápidas e de curta duração. É muito inadequado para cargas de trabalho de E / S de bloqueio demoradas e demoradas, por exemplo, cargas de trabalho que envolvam a chamada de APIs HTTP.
  • Puramente multiencadeado. Atualmente, o ecossistema Ruby possui excelente suporte a multithreading, portanto esse modelo de E / S se tornou muito viável. O multithreading permite alta simultaneidade de E / S, tornando-o adequado para cargas de trabalho de E / S de bloqueio de execução curta e longa. É mais provável que o programador introduza bugs de simultaneidade, mas felizmente a maioria das estruturas da Web é projetada de tal maneira que isso ainda é muito improvável. Uma coisa a ser observada, porém, é que o interpretador MRI Ruby não pode alavancar vários núcleos de CPU, mesmo quando há vários threads, devido ao uso do Global Interpreter Lock (GIL). Você pode contornar isso usando vários processos multithread, porque cada processo pode alavancar um núcleo de CPU. O JRuby e o Rubinius não têm GIL, portanto, eles podem aproveitar totalmente vários núcleos em um único processo.
  • Multi-processo híbrido multithread. Implementado principalmente pelo Phusion Passenger Enterprise 4 e posterior. É possível alternar facilmente entre processos múltiplos de thread único, multithreaded ou até vários processos, cada um com vários threads. Este modelo oferece o melhor dos dois mundos.
  • Evented. Este modelo é completamente diferente do modelo mencionado anteriormente. Ele permite simultaneidade de E / S muito alta e, portanto, é excelente para cargas de trabalho de E / S de bloqueio de longa execução. Para utilizá-lo, é necessário suporte explícito do aplicativo e da estrutura. No entanto, todas as principais estruturas, como Rails e Sinatra, não suportam código de eventos. É por isso que, na prática, um processo Thin ainda não pode lidar com mais de uma solicitação por vez, fazendo com que ele se comporte efetivamente da mesma forma que o modelo de processos múltiplos de thread único. Existem estruturas especializadas que podem tirar proveito de E / S registrada, como o Cramp.

Um artigo foi publicado recentemente no blog Phusion sobre o ajuste ideal do número de processos e encadeamentos, dada a sua carga de trabalho. Consulte Ajustando as configurações de simultaneidade do Phusion Passenger .

Capistrano

Capistrano é algo completamente diferente. Em todas as seções anteriores, "implantação" refere-se ao ato de iniciar seu aplicativo Ruby em um servidor de aplicativos, para que ele se torne acessível aos visitantes, mas antes que isso aconteça, normalmente é necessário fazer algum trabalho de preparação, como:

  • Carregar o código e os arquivos do aplicativo Ruby na máquina do servidor.
  • Instalando bibliotecas das quais seu aplicativo depende.
  • Configurando ou migrando o banco de dados.
  • Iniciando e parando quaisquer daemons nos quais seu aplicativo possa confiar, como funcionários do Sidekiq / Resque ou o que quer.
  • Quaisquer outras coisas que precisam ser feitas quando você estiver configurando seu aplicativo.

No contexto de Capistrano, "implantação" refere-se a fazer todo esse trabalho de preparação. Capistrano não é um servidor de aplicativos. Em vez disso, é uma ferramenta para automatizar todo esse trabalho de preparação. Você diz ao Capistrano onde está o servidor e quais comandos precisam ser executados toda vez que você implantar uma nova versão do seu aplicativo, e o Capistrano se encarregará de carregar o aplicativo Rails no servidor e executar os comandos que você especificou.

O Capistrano é sempre usado em combinação com um servidor de aplicativos. Não substitui servidores de aplicativos. Vice-versa, os servidores de aplicativos não substituem o Capistrano, eles podem ser usados ​​em combinação com o Capistrano.

Claro que você não precisa usar o Capistrano. Se você preferir carregar seu aplicativo Ruby com FTP e executar manualmente as mesmas etapas de comandos todas as vezes, poderá fazer isso. Outras pessoas se cansaram, e automatizaram essas etapas em Capistrano.

Hongli
fonte
74
Você deve publicar isso em algum lugar. Agora tudo é fácil, mas quando comecei com os trilhos, era difícil obter informações úteis.
Spegoraro
9
Excelente postagem! Também esclareceu muito para mim. Você deve adicionar outros elementos, como bundler e rvm, e torná-lo um post de blog pesado! :)
Damien Roche
37
Isso precisa estar nos guias do Rails.
Dorian
4
"Ninguém usa o WEBrick em ambientes de produção." Isto não é verdade, de forma alguma. O servidor de aplicativos padrão ao enviar aplicativos ruby ​​para o heroku é o webrick.
John Downey
37
@ Hongli Este post é muito favorável ao Phusion Passenger. Talvez seja sensato adicionar sua afiliação ao projeto (CTO, phusion.nl/about ) por uma questão de objetividade?
Bert Goethals