Essa resposta é complementar às outras e explica por que o Unicorn precisa de nginx na frente dele .
TL; DR O motivo pelo qual o Unicorn geralmente é implantado junto com um proxy reverso como o nginx é porque seus criadores o projetaram deliberadamente, fazendo uma troca pela simplicidade.
Primeiro de tudo, não há nada que impeça a implantação do Unicorn sem um proxy reverso. No entanto, isso não seria uma boa ideia; vamos ver o porquê.
O Unicorn segue a filosofia do Unix, que consiste em fazer uma coisa e fazê-lo bem , e servir clientes rápidos e de baixa latência (veremos o que isso significa mais adiante). O fato de o Unicorn ser projetado para clientes rápidos e de baixa latência também implica que não é muito bom para clientes lentos e de alta latência , o que é realmente verdade. Esse é um dos pontos fracos do Unicorn e é onde um proxy reverso entra em cena: ele fica na frente do Unicorn e cuida desses clientes lentos (veremos mais adiante).
Felizmente, esse proxy reverso já existe e é chamado nginx .
A decisão de lidar apenas com clientes rápidos, simplifica muito o design do Unicorn e permite uma base de código muito mais simples e menor, com o custo de uma complexidade adicional no departamento de implantação (ou seja, você também deve implantar o nginx além do Unicorn).
Uma decisão alternativa poderia ser projetar o Unicorn de tal maneira que não fosse necessário um proxy reverso. No entanto, isso significa que seria necessário implementar funcionalidades extras para fazer tudo o que o nginx faz agora, resultando em uma base de código mais complexa e em mais esforços de engenharia.
Em vez disso, seus criadores tomaram a decisão de aproveitar o software existente testado em batalha e muito bem projetado e evitar desperdiçar tempo e energia em problemas já resolvidos por outros softwares.
Mas vamos ser técnicos e responder à sua pergunta:
Por que o Unicorn precisa ser implantado junto com o nginx?
Aqui estão alguns dos principais motivos:
O Unicorn usa E / S de bloqueio para clientes
Confiar em um proxy reverso significa que o Unicorn não precisa usar E / S sem bloqueio. Em vez disso, pode usar E / S de bloqueio, que é inerentemente mais simples e fácil para o programador seguir.
Também como o documento DESIGN afirma:
[Usar bloqueio de E / S] permite que um caminho de código mais simples seja seguido no interpretador Ruby e menos syscalls.
No entanto, isso também tem algumas consequências:
Ponto-chave nº 1: o unicórnio não é eficiente com clientes lentos
(Por uma questão de simplicidade, assumimos uma configuração com 1 trabalhador Unicorn)
Como o bloqueio de E / S é usado, um trabalhador Unicorn pode servir apenas um cliente por vez , portanto, um cliente lento (por exemplo, um com uma conexão lenta) manteria efetivamente o trabalhador ocupado por mais tempo (do que um cliente rápido faria) ) Enquanto isso, os outros clientes esperariam até o trabalhador ficar livre novamente (ou seja, os pedidos se acumulariam na fila).
Para contornar esse problema, um proxy reverso é implantado na frente do Unicorn, que armazena em buffer totalmente as solicitações recebidas e as respostas do aplicativo e envia cada uma delas de uma só vez (também conhecida como colher) para o Unicorn e os clientes, respectivamente. A esse respeito, você poderia dizer que o proxy reverso "protege" o Unicorn de clientes de rede lentos.
Felizmente, o Nginx é um ótimo candidato para essa função, pois foi projetado para lidar com milhares de centenas de clientes simultâneos com eficiência.
É de importância crucial que o proxy reverso esteja dentro da mesma rede local que o Unicorn (normalmente na mesma máquina física que se comunica com o Unicorn por meio de um soquete de domínio Unix), para que a latência da rede seja mantida no mínimo.
Portanto, esse proxy efetivamente desempenha o papel de um cliente rápido que o Unicorn foi projetado para atender em primeiro lugar, uma vez que solicita proxies ao Unicorn rapidamente e mantém os trabalhadores ocupados pelo menor tempo possível (em comparação com quanto tempo um cliente com uma conexão lenta faria).
Ponto-chave 2: O Unicorn não suporta HTTP / 1.1 keep-alive
Como o Unicorn usa E / S de bloqueio, isso também significa que ele não pode suportar o recurso de manutenção de HTTP / 1.1, pois as conexões persistentes de clientes lentos ocupariam rapidamente todos os trabalhadores disponíveis do Unicorn.
Portanto, para aproveitar o HTTP keep-alive, adivinhe: um proxy reverso é usado.
Por outro lado, o nginx pode lidar com milhares de conexões simultâneas usando apenas alguns threads. Portanto, ele não possui os limites de simultaneidade que um servidor como o Unicorn possui (o que basicamente se limita à quantidade de processos do trabalhador), o que significa que ele pode lidar com conexões persistentes muito bem. Mais sobre como isso realmente funciona pode ser encontrado aqui .
É por isso que o nginx aceita conexões keep-alive dos clientes e as envia para o Unicorn por meio de conexões simples por meio de um soquete Unix.
Ponto # 3: Unicorn não é muito bom em servir arquivos estáticos
Novamente, servir arquivos estáticos é algo que o Unicorn pode fazer, mas não foi projetado para fazer com eficiência.
Por outro lado, proxies reversos como o nginx são muito melhores nisso (isto é, sendfile(2)
& cache).
Mais
Existem outros pontos descritos no documento FILOSOFIA (consulte "Desempenho aprimorado por meio de proxy reverso" ).
Veja também alguns dos recursos básicos do nginx .
Vemos que, aproveitando o software existente (por exemplo, nginx) e seguindo a filosofia do Unix de "fazer uma coisa e fazer bem", o Unicorn consegue seguir um design e implementação mais simples, mantendo a eficiência no atendimento aos aplicativos Rack (por exemplo, seu aplicativo Rails).
Para obter mais informações, consulte a filosofia e os documentos de design do Unicorn, que explicam mais detalhadamente as opções por trás do design do Unicorn e por que o nginx é considerado um bom proxy reverso para o Unicorn.