Perché ho bisogno di Nginx e qualcosa come Gunicorn?


219

Sto cercando una risposta eccessivamente semplificata alla seguente domanda. Sto cercando di costruire una comprensione di base di come Nginx lavora a fianco di qualcosa come Gunicorn.

Ho bisogno sia di Nginx che di qualcosa come Gunicorn per distribuire app Django su Nginx?

In tal caso, cosa gestisce effettivamente le richieste HTTP?

Ps. Non voglio usare Apache e mod_wsgi!


Apache e mod_wsgi è il modo più semplice per implementare il bridge tra l'applicazione django e le richieste http che è anche molto capace in un ambiente di produzione. Per molti sviluppatori, questo significa che "Apache è meglio di nginx" se lo sapessero ma lo sapessero, ma poiché "betamax è meglio di VHS", ahimè, le regole Dogma
MagicLAMP

Risposte:


314

Semplificato eccessivamente: è necessario qualcosa che esegua Python ma Python non è il migliore nel gestire tutti i tipi di richieste.

[dichiarazione di non responsabilità: sono uno sviluppatore di Gunicorn]

Meno semplificato: indipendentemente dal server di app che usi (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy) qualsiasi tipo di distribuzione non banale avrà qualcosa a monte che gestirà le richieste che la tua app Django non dovrebbe gestire. Esempi fondamentali di tali richieste sono al servizio di risorse statiche (images / css / js).

Ciò si traduce in due primi livelli della classica "architettura a tre livelli". Vale a dire, il server web (Nginx nel tuo caso) gestirà molte richieste di immagini e risorse statiche. Le richieste che devono essere generate dinamicamente verranno quindi passate al server delle applicazioni (Gunicorn nel tuo esempio). (A parte il terzo dei tre livelli è il database)

Storicamente parlando, ciascuno di questi livelli sarebbe ospitato su macchine separate (e molto probabilmente ci sarebbero più macchine nei primi due livelli, ovvero: 5 server web inviano richieste a due server di app che a loro volta interrogano un singolo database).

Nell'era moderna ora abbiamo applicazioni di tutte le forme e dimensioni. Non tutti i progetti di fine settimana o siti di piccole imprese hanno effettivamente bisogno della potenza di più macchine e funzioneranno abbastanza felicemente su una singola scatola. Ciò ha generato nuove voci nell'array di soluzioni di hosting. Alcune soluzioni sposano l'app server con il web server (Apache httpd + mod_wsgi, Nginx + mod_uwsgi, ecc.). E non è affatto raro ospitare il database sullo stesso computer di una di queste combinazioni di server web / app.

Ora, nel caso di Gunicorn, abbiamo preso una decisione specifica (copiando dall'unicorno di Ruby) per mantenere le cose separate da Nginx facendo affidamento sul comportamento di Nginx. In particolare, se possiamo supporre che Gunicorn non leggerà mai le connessioni direttamente da Internet, non dovremo preoccuparci dei client lenti. Ciò significa che il modello di elaborazione per Gunicorn è imbarazzantemente semplice.

La separazione consente inoltre di scrivere Gunicorn in puro Python, riducendo al minimo i costi di sviluppo senza influire in modo significativo sulle prestazioni. Inoltre, consente agli utenti di utilizzare altri proxy (supponendo che si bufferizzino correttamente).

Per quanto riguarda la tua seconda domanda su ciò che gestisce effettivamente la richiesta HTTP, la risposta semplice è Gunicorn. La risposta completa è che Nginx e Gunicorn gestiscono la richiesta. Fondamentalmente, Nginx riceverà la richiesta e, se si tratta di una richiesta dinamica (generalmente basata su pattern URL), fornirà tale richiesta a Gunicorn, che la elaborerà e quindi restituirà una risposta a Nginx che quindi inoltra la risposta all'originale cliente.

Quindi in chiusura sì. Hai bisogno di Nginx e Gunicorn (o qualcosa di simile) per una corretta distribuzione di Django. Se stai specificatamente cercando di ospitare Django con Nginx, indagherei Gunicorn, mod_uwsgi e forse CherryPy come candidati per il lato Django delle cose.


14
Grazie per aver dedicato del tempo a scrivere una risposta così dettagliata! Qualche consiglio consigliato su questa "architettura a 3 livelli"?
Sono

5
Ottima risposta, tuttavia non capisco il problema con i client lenti.
Mads Skjern,

3
@MadsSkjern Sto indovinando qui, ma se si presume che tutti i client siano veloci, è possibile utilizzare un pool fisso di processi di lavoro e non è necessario codificare il caso in cui molti o tutti vengono bloccati in attesa di un client.
Jonathan Hartley,


7
la mia app django serve solo a json nessun contenuto statico posso solo andare con gunicorn e no nginx
Sar009

27

Mi è piaciuta questa spiegazione nella sua semplicità:

Nginx affronterà il mondo esterno. Servirà file multimediali (immagini, CSS, ecc.) Direttamente dal file system. Tuttavia, non può parlare direttamente con le applicazioni Django; ha bisogno di qualcosa che eseguirà l'applicazione, fornirà le richieste dal Web e restituirà le risposte.

Questo è il lavoro di Gunicorn. Gunicorn creerà un socket Unix e fornirà le risposte a nginx tramite il protocollo wsgi - il socket passa i dati in entrambe le direzioni:

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

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


Non devono essere prese, nel caso in cui gli altri si chiedano.
akshay,

0

Sto cercando una risposta eccessivamente semplificata ...

Ho bisogno sia di Nginx che di qualcosa come Gunicorn per distribuire app Django su Nginx?

In tal caso, cosa gestisce effettivamente le richieste HTTP?

Risposta eccessivamente semplificata:

SÌ.

Sia Nginx che Gunicorn.

Dato che stai distribuendo su Nginx, ovviamente hai bisogno di Nginx.

Dal momento che stai implementando Django, che è un framework web, hai bisogno di qualcosa che collega il web server (Nginx) e il framework web (Django). Nel mondo Python, una cosa del genere si chiama server WSGI (ma lo si pensa come un prodotto intermedio), esempi dei quali includono Gunicorn e uWSGI. Quando gestisce una richiesta, Nginx inoltra la richiesta a Gunicorn o uWSGI, che a sua volta chiama il codice Django e restituisce la risposta.

Questo documento e la risposta di Paul ti aiuteranno a impararlo meglio.


0

Gunicorn è uno spreco di risorse. Puoi semplicemente passare il proxy a django ascoltando su una porta invece di eseguire gunicorn su django superiore e di nuovo nginx su tutto ciò. Nei benchmark, ho visto un notevole aumento della velocità. Nginx può facilmente gestire richieste dirette a django. Gunicorn non è altro che un cavalcavia (in realtà un cavalcavia più lento) sopra la strada normale. Si siede e mangia le tue risorse e cerca di affermare di alimentare il tuo sito web.

nginx fondamentalmente buffer tutte le richieste e gestisce le richieste di file statici da solo (se è stato configurato in questo modo). E inoltra tutto il contenuto dinamico a un altro server (gunicorn / django).

Gunicorn non ha altro uso che passare la richiesta all'applicazione. È come una cannuccia che puoi bere direttamente dal bicchiere o bere dalla paglia a un ritmo limitato (qui la persona che beve è django). E nginx è il cameriere che ti ha portato il bicchiere di succo.

Ho analizzato e trovato questo - con gunicorn: 22k req / s senza gunicorn: 34k req / s

Il tuo sito avrà bisogno di ulteriori richieste in caso di carichi pesanti.


1
Stai parlando di eseguire il server di sviluppo in produzione ?!
Michael Hampton

Il server di sviluppo può essere eseguito dietro un server di produzione (come nginx). Perché riceverà le richieste nella posizione corretta e la sicurezza e l'efficienza saranno gestite dal server di produzione. È come usare solo il pallone WSGI +. Invece puoi usare solo nginx + django (senza alcun hogging del middleware, come il gunicorn). Si prega di testare l'installazione su carichi pesanti e capirai.
ShadowDoom

1
github.com/django/channels/issues/142 (TLDR: è una cattiva idea)
igor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.