Por que preciso do Nginx e algo como Gunicorn?

219

Estou procurando uma resposta excessivamente simplificada para a seguinte pergunta. Estou tentando construir um entendimento básico de como o Nginx funciona ao lado de algo como Gunicorn.

Preciso do Nginx e de algo como o Gunicorn para implantar aplicativos Django no Nginx?

Se sim, o que realmente lida com as solicitações HTTP?

Ps. Eu não quero usar Apache e mod_wsgi!

sou
fonte
Apache e mod_wsgi é a maneira mais simples de implementar a ponte entre seu aplicativo django e solicitações http, que também é muito capaz em um ambiente de produção. Para muitos desenvolvedores, isso significa 'Apache é melhor que nginx' se eles soubessem, mas como 'betamax é melhor que VHS', infelizmente, regras de Dogma
MagicLAMP

Respostas:

314

Simplificado demais: você precisa de algo que execute o Python, mas o Python não é o melhor para lidar com todos os tipos de solicitações.

[aviso: sou desenvolvedor do Gunicorn]

Menos simplificado: independentemente do servidor de aplicativos que você usa (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy), qualquer tipo de implantação não trivial terá algo a montante que manipulará as solicitações que seu aplicativo Django não deve atender. Exemplos triviais de tais solicitações estão servindo ativos estáticos (images / css / js).

Isso resulta em duas primeiras camadas da clássica "arquitetura de três camadas". Ou seja, o servidor da web (Nginx no seu caso) atenderá a muitos pedidos de imagens e recursos estáticos. Solicitações que precisam ser geradas dinamicamente serão repassadas ao servidor de aplicativos (Gunicorn no seu exemplo). (Como um aparte, o terceiro dos três níveis é o banco de dados)

Historicamente, cada uma dessas camadas seria hospedada em máquinas separadas (e provavelmente haveria várias máquinas nas duas primeiras camadas, ou seja: 5 servidores da Web enviam solicitações para dois servidores de aplicativos que, por sua vez, consultam um único banco de dados).

Na era moderna, agora temos aplicações de todas as formas e tamanhos. Nem todo projeto de fim de semana ou site de empresa de pequeno porte realmente precisa da potência de várias máquinas e funciona muito bem em uma única caixa. Isso gerou novas entradas no conjunto de soluções de hospedagem. Algumas soluções casarão o servidor de aplicativos com o servidor Web (Apache httpd + mod_wsgi, Nginx + mod_uwsgi, etc). E não é incomum hospedar o banco de dados na mesma máquina que uma dessas combinações de servidores de aplicativos / web.

Agora, no caso de Gunicorn, tomamos uma decisão específica (copiando do Ruby Unicorn) de manter as coisas separadas do Nginx enquanto confiamos no comportamento de proxy do Nginx. Especificamente, se pudermos supor que o Gunicorn nunca lerá conexões diretamente da Internet, não precisaremos nos preocupar com clientes que são lentos. Isso significa que o modelo de processamento do Gunicorn é embaraçosamente simples.

A separação também permite que o Gunicorn seja escrito em Python puro, o que minimiza o custo do desenvolvimento sem afetar significativamente o desempenho. Ele também permite que os usuários usem outros proxies (supondo que sejam armazenados em buffer corretamente).

Quanto à sua segunda pergunta sobre o que realmente lida com a solicitação HTTP, a resposta simples é Gunicorn. A resposta completa é que Nginx e Gunicorn tratam da solicitação. Basicamente, o Nginx receberá a solicitação e, se for uma solicitação dinâmica (geralmente baseada em padrões de URL), enviará essa solicitação ao Gunicorn, que a processará e, em seguida, retornará uma resposta ao Nginx, que encaminhará a resposta ao original. cliente.

Então, fechando, sim. Você precisa do Nginx e do Gunicorn (ou algo semelhante) para uma implementação apropriada do Django. Se você está procurando hospedar o Django especificamente com o Nginx, eu investigaria o Gunicorn, mod_uwsgi e talvez o CherryPy como candidatos ao lado do Django.

Paul J. Davis
fonte
14
Obrigado por escrever uma resposta tão detalhada! Alguma leitura recomendada sobre esta "arquitetura de três camadas"?
am
5
Ótima resposta, porém não entendo o problema com clientes lentos.
precisa saber é o seguinte
3
@MadsSkjern Acho que estou aqui, mas se você assumir que todos os clientes são rápidos, poderá usar um pool fixo de processos de trabalho e não precisar codificar o caso em que muitos ou todos eles ficam bloqueados esperando por um cliente.
Jonathan Hartley
7
meu aplicativo django só serve json nenhum conteúdo estático i pode simplesmente ir com gunicorn e nenhum nginx
Sar009
27

Gostei desta explicação em sua simplicidade:

O Nginx enfrentará o mundo exterior. Servirá arquivos de mídia (imagens, CSS, etc) diretamente do sistema de arquivos. No entanto, ele não pode falar diretamente com aplicativos Django; ele precisa de algo que execute o aplicativo, alimente solicitações da Web e retorne respostas.

Esse é o trabalho de Gunicorn. O Gunicorn criará um soquete Unix e fornecerá respostas ao nginx por meio do protocolo wsgi - o soquete passa os dados nas duas direções:

The outside world <-> Nginx <-> The socket <-> Gunicorn

https://gist.github.com/Atem18/4696071

Juuso Ohtonen
fonte
Não precisa ser soquetes, apenas no caso de outros estarem se perguntando.
akshay
0

Estou procurando uma resposta excessivamente simplificada ...

Preciso do Nginx e de algo como o Gunicorn para implantar aplicativos Django no Nginx?

Se sim, o que realmente lida com as solicitações HTTP?

Resposta excessivamente simplificada:

SIM.

Nginx e Gunicorn.

Desde que você está implantando no Nginx, é claro que você precisa do Nginx.

Como você está implantando o Django, que é uma estrutura da web, você precisa de algo que faça a ponte entre o servidor da web (Nginx) e a estrutura da web (Django). No mundo Python, isso é chamado de servidor WSGI (mas pense como um meio), cujos exemplos incluem Gunicorn e uWSGI. Ao manipular uma solicitação, o Nginx faz proxy da solicitação para Gunicorn ou uWSGI, que por sua vez chama o código Django e retorna a resposta.

Este documento e a resposta de Paulo o ajudarão a aprender melhor.

Cyker
fonte
0

Gunicorn é um desperdício de recursos. Você pode simplesmente passar por proxy para o django ouvindo em uma porta, em vez de executar o gunicorn no topo do django e novamente o nginx no topo de tudo isso. Nos benchmarks, eu vi um aumento de velocidade muito perceptível. O Nginx pode lidar facilmente com solicitações diretas ao django. Gunicorn nada mais é do que um viaduto (na verdade um viaduto mais lento) acima da estrada normal. Ele apenas senta e consome seus recursos e tenta reivindicar estar alimentando seu site.

O nginx basicamente armazena em buffer todas as solicitações e lida com as solicitações de arquivo estático por si só (se você tiver configurado dessa maneira). E proxies todo o conteúdo dinâmico para outro servidor. (Gunicorn / django).

O Gunicorn não tem outro uso senão apenas passar a solicitação para o aplicativo. É como um canudo que você pode beber diretamente do copo ou beber a um ritmo limitado (aqui a pessoa que bebe é django). E nginx é o garçom que lhe trouxe o copo de suco.

Comparei e encontrei isso - com gunicorn: 22k req / s sem gunicorn: 34k req / s

Seu site precisará de req / s extras em carga pesada.

ShadowDoom
fonte
1
Você está falando em executar o servidor de desenvolvimento em produção ?!
Michael Hampton
O servidor de desenvolvimento pode ser executado atrás de um servidor de produção (como nginx). Como ele estará recebendo solicitações no local correto, a segurança e a eficiência serão tratadas pelo servidor de produção. É como usar apenas o WSGI + balão. Em vez disso, você pode usar apenas nginx + django (sem nenhum uso de middleware, como o gunicorn). Teste a configuração em carga pesada e você entenderá.
ShadowDoom
1
github.com/django/channels/issues/142 (TLDR: é uma péssima idéia)
igor