Dlaczego potrzebuję Nginx i czegoś takiego jak Gunicorn?


219

Szukam zbyt uproszczonej odpowiedzi na następujące pytanie. Próbuję zbudować fundamentalne zrozumienie, w jaki sposób Nginx działa obok czegoś takiego jak Gunicorn.

Czy potrzebuję zarówno Nginx, jak i Gunicorn do wdrażania aplikacji Django na Nginx?

Jeśli tak, co faktycznie obsługuje żądania HTTP?

Ps. Nie chcę używać Apache i mod_wsgi!


Apache i mod_wsgi to najprostszy sposób implementacji pomostu między aplikacją django a żądaniami HTTP, który jest również bardzo wydajny w środowisku produkcyjnym. Dla wielu programistów oznacza to, że „Apache jest lepszy niż nginx”, jeśli wie, ale o tym wie, ale ponieważ „betamax jest lepszy niż VHS”, niestety zasady Dogma
MagicLAMP

Odpowiedzi:


314

Zbyt uproszczone: potrzebujesz czegoś, co uruchamia Pythona, ale Python nie jest najlepszy w obsłudze wszystkich typów żądań.

[zastrzeżenie: Jestem programistą Gunicorn]

Mniej uproszczone: Niezależnie od tego, jakiego serwera aplikacji używasz (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy), każde nietrywialne wdrożenie będzie miało coś upstream, który obsłuży żądania, których twoja aplikacja Django nie powinna obsługiwać. Trywialnymi przykładami takich żądań są zasoby statyczne (images / css / js).

Powoduje to powstanie dwóch pierwszych poziomów klasycznej „architektury trzypoziomowej”. Tzn. Serwer WWW (w twoim przypadku Nginx) obsłuży wiele żądań obrazów i zasobów statycznych. Żądania, które muszą być generowane dynamicznie, zostaną następnie przekazane do serwera aplikacji (w Twoim przykładzie Gunicorn). (Nawiasem mówiąc, trzeci z trzech poziomów to baza danych)

Historycznie rzecz biorąc, każda z tych warstw byłaby hostowana na osobnych komputerach (i najprawdopodobniej w dwóch pierwszych warstwach byłoby wiele komputerów, tj .: 5 serwerów WWW wysyła żądania do dwóch serwerów aplikacji, które z kolei odpytują jedną bazę danych).

W erze współczesnej mamy teraz aplikacje wszystkich kształtów i rozmiarów. Nie w każdy weekendowy projekt lub strona małej firmy faktycznie potrzebuje mocy wielu maszyn i będzie działać całkiem szczęśliwie na jednym pudełku. Spowodowało to pojawienie się nowych wpisów w szeregu rozwiązań hostingowych. Niektóre rozwiązania będą łączyć serwer aplikacji z serwerem WWW (Apache httpd + mod_wsgi, Nginx + mod_uwsgi itp.). I wcale nie jest rzadkością hostowanie bazy danych na tym samym komputerze, co jedna z tych kombinacji serwera WWW / aplikacji.

Teraz w przypadku Gunicorn podjęliśmy konkretną decyzję (kopiowanie z Unicorn Ruby), aby oddzielić rzeczy od Nginx, polegając na zachowaniu proxy Nginx. W szczególności, jeśli możemy założyć, że Gunicorn nigdy nie będzie czytać połączeń bezpośrednio z Internetu, nie musimy martwić się o klientów, którzy działają wolno. Oznacza to, że model przetwarzania dla Gunicorn jest krępująco prosty.

Rozdzielenie pozwala również na pisanie Gunicorn w czystym Pythonie, co minimalizuje koszty rozwoju, ale nie wpływa znacząco na wydajność. Umożliwia także użytkownikom korzystanie z innych serwerów proxy (przy założeniu, że buforują poprawnie).

Jeśli chodzi o twoje drugie pytanie dotyczące tego, co faktycznie obsługuje żądanie HTTP, prostą odpowiedzią jest Gunicorn. Pełna odpowiedź brzmi: zarówno Nginx, jak i Gunicorn obsługują żądanie. Zasadniczo, Nginx otrzyma żądanie, a jeśli jest to żądanie dynamiczne (zwykle oparte na wzorcach adresów URL), wówczas przekaże to żądanie Gunicorn, który je przetworzy, a następnie zwróci odpowiedź do Nginx, który następnie przekaże odpowiedź z powrotem do oryginału klient.

A więc na zakończenie tak. Do prawidłowego wdrożenia Django potrzebujesz zarówno Nginx, jak i Gunicorn (lub czegoś podobnego). Jeśli szczególnie chcesz hostować Django z Nginx, zbadałbym Gunicorn, mod_uwsgi, a może CherryPy jako kandydatów na stronę Django.


14
Dziękujemy za poświęcenie czasu na napisanie tak szczegółowej odpowiedzi! Czy jest jakaś rekomendowana lektura na temat „architektury trójwarstwowej”?
Jestem

5
Świetna odpowiedź, jednak nie rozumiem problemu z powolnymi klientami.
Mads Skjern

3
@MadsSkjern Zgaduję tutaj, ale jeśli zakładasz, że wszyscy klienci są szybcy, możesz użyć stałej puli procesów roboczych i nie musisz kodować na wypadek, gdy wielu lub wszystkich z nich zostanie zablokowanych w oczekiwaniu na klienta.
Jonathan Hartley,


7
moja aplikacja django obsługuje tylko JSON, bez zawartości statycznej, mogę po prostu iść z gunicorn i bez Nginx
Sar009

27

Podobało mi się to wyjaśnienie w swojej prostocie:

Nginx zmierzy się ze światem zewnętrznym. Będzie obsługiwał pliki multimedialne (obrazy, CSS itp.) Bezpośrednio z systemu plików. Nie może jednak komunikować się bezpośrednio z aplikacjami Django; potrzebuje czegoś, co uruchomi aplikację, nakarmi jej żądania z sieci i zwróci odpowiedzi.

To praca Gunicorn. Gunicorn utworzy gniazdo Unix i będzie obsługiwać odpowiedzi na nginx za pośrednictwem protokołu wsgi - gniazdo przekazuje dane w obu kierunkach:

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

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


Nie muszą to być gniazda, na wypadek, gdyby inni się zastanawiali.
akshay,

0

Szukam zbyt uproszczonej odpowiedzi ...

Czy potrzebuję zarówno Nginx, jak i Gunicorn do wdrażania aplikacji Django na Nginx?

Jeśli tak, co faktycznie obsługuje żądania HTTP?

Zbyt uproszczona odpowiedź:

TAK.

Zarówno Nginx, jak i Gunicorn.

Ponieważ wdrażasz na Nginx, oczywiście potrzebujesz Nginx.

Ponieważ wdrażasz Django, który jest strukturą internetową, potrzebujesz czegoś, co pomija rozmowę między serwerem WWW (Nginx) a strukturą internetową (Django). W świecie Python takie coś nazywa się serwerem WSGI (ale myślę, że to jak oprogramowanie pośrednie), którego przykładami są Gunicorn i uWSGI. Podczas obsługi żądania Nginx przekazuje zapytanie do Gunicorn lub uWSGI, który z kolei wywołuje kod Django i zwraca odpowiedź.

Ten dokument i odpowiedź Paula pomogą ci się go lepiej nauczyć.


0

Gunicorn to marnowanie zasobów. Możesz po prostu przekazać proxy do django nasłuchującego na porcie zamiast uruchamiać gunicorn na górnym django i ponownie nginx na tym wszystkim. W testach porównawczych zauważyłem bardzo zauważalny wzrost prędkości. Nginx może z łatwością obsługiwać bezpośrednie żądania do django. Gunicorn to nic innego jak estakada (właściwie wolniejsza estakada) nad normalną drogą. Po prostu siedzi i zjada twoje zasoby i próbuje twierdzić, że napędza twoją stronę.

nginx zasadniczo buforuje wszystkie żądania i sam obsługuje żądania plików statycznych (jeśli tak to skonfigurowałeś). I przekazuje całą dynamiczną zawartość do innego serwera. (Gunicorn / django).

Gunicorn nie ma innego zastosowania niż przekazanie wniosku do aplikacji. To jak słomka, którą możesz pić bezpośrednio ze szklanki lub pić ze słomy w ograniczonym tempie (tutaj osobą pijącą jest django). A Nginx jest kelnerem, który przyniósł ci szklankę soku.

Przeprowadziłem testy porównawcze i znalazłem to - z gunicorn: 22k req / s bez gunicorn: 34k req / s

Twoja strona będzie potrzebować dodatkowych wymagań / s przy dużym obciążeniu.


1
Czy mówisz o uruchomieniu serwera programistycznego w produkcji ?!
Michael Hampton

Serwer programistyczny można uruchomić za serwerem produkcyjnym (takim jak nginx). Ponieważ będzie otrzymywał żądania we właściwym miejscu, a bezpieczeństwo i wydajność będą obsługiwane przez serwer produkcyjny. To tak, jakby używać tylko kolby WSGI +. Zamiast tego możesz użyć po prostu nginx + django (bez zbędnego pośrednictwa, jak gunicorn). Sprawdź konfigurację przy dużym obciążeniu, a zrozumiesz.
ShadowDoom

1
github.com/django/channels/issues/142 (TLDR: to zły pomysł)
igor
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.