Podczas uruchamiania serwera deweloperskiego - co uzyskujesz uruchamiając app.run()
, uzyskujesz pojedynczy proces synchroniczny, co oznacza, że maksymalnie 1 żądanie jest przetwarzane na raz.
Trzymając Gunicorn przed nim w jego domyślnej konfiguracji i po prostu zwiększając liczbę --workers
, otrzymujesz zasadniczo liczbę procesów (zarządzanych przez Gunicorn), z których każdy zachowuje się jak app.run()
serwer deweloperski. 4 pracowników == 4 jednoczesne żądania. Dzieje się tak, ponieważ Gunicorn domyślnie używa dołączonego sync
typu pracownika.
Ważne jest, aby zauważyć, że Gunicorn obejmuje również pracowników asynchronicznych, a mianowicie eventlet
i gevent
(a także tornado
, ale wydaje się, że najlepiej jest to używać z frameworkiem Tornado). Określając jednego z tych pracowników asynchronicznych za pomocą --worker-class
flagi, otrzymujesz Gunicorn zarządzający wieloma procesami asynchronicznymi, z których każdy zarządza własną współbieżnością. W tych procesach nie są używane wątki, ale programy. Zasadniczo w każdym procesie może się zdarzyć tylko 1 rzecz naraz (1 wątek), ale obiekty można „wstrzymać”, gdy oczekują na zakończenie procesów zewnętrznych (pomyśl o zapytaniach do bazy danych lub oczekiwaniu na operacje we / wy sieci).
Oznacza to, że jeśli używasz jednego z pracowników asynchronicznych Gunicorn, każdy pracownik może obsłużyć więcej niż jedno żądanie na raz. To, ilu pracowników jest najlepsze, zależy od charakteru aplikacji, jej środowiska, sprzętu, na którym działa, itp. Więcej szczegółów można znaleźć na stronie projektu Gunicorn i uwagach na temat działania gevent na stronie wprowadzającej.
Obecnie istnieje dużo prostsze rozwiązanie niż te już dostarczone. Podczas uruchamiania aplikacji wystarczy przekazać
threaded=True
parametr doapp.run()
wywołania, na przykład:app.run(host="your.host", port=4321, threaded=True)
Inną opcją, zgodnie z tym, co widzimy w dokumentach werkzeug , jest użycie
processes
parametru, który otrzymuje liczbę> 1 wskazującą maksymalną liczbę współbieżnych procesów do obsłużenia:Coś jak:
app.run(host="your.host", port=4321, processes=3) #up to 3 processes
Więcej informacji na temat
run()
metody można znaleźć tutaj , oraz w poście na blogu, który doprowadził mnie do znalezienia rozwiązania i odniesień do interfejsu API.Uwaga: w dokumentacji Flask na temat
run()
metod wskazano, że używanie go w środowisku produkcyjnym jest odradzane, ponieważ ( cytat ): „Chociaż jest lekki i łatwy w użyciu, wbudowany serwer Flask nie nadaje się do produkcji, ponieważ nie skaluje się dobrze ”.Wskazują jednak na stronę Opcje wdrażania, aby zapoznać się z zalecanymi sposobami zrobienia tego podczas przechodzenia do produkcji.
źródło
Flask będzie przetwarzać jedno żądanie na wątek w tym samym czasie. Jeśli masz 2 procesy, każdy z 4 wątkami, oznacza to 8 jednoczesnych żądań.
Flask nie uruchamia się ani nie zarządza wątkami ani procesami. To jest odpowiedzialność bramy WSGI (np. Gunicorn).
źródło
Nie - zdecydowanie poradzisz sobie z czymś więcej.
Ważne jest, aby pamiętać, że w głębi duszy, zakładając, że używasz maszyny z jednym rdzeniem, procesor tak naprawdę wykonuje tylko jedną instrukcję * na raz.
Mianowicie, procesor może wykonać tylko bardzo ograniczony zestaw instrukcji i nie może wykonać więcej niż jednej instrukcji na takt zegara (wiele instrukcji zajmuje nawet więcej niż 1 takt).
Dlatego większość współbieżności, o której mówimy w informatyce, to współbieżność oprogramowania. Innymi słowy, istnieją warstwy implementacji oprogramowania, które odejmują od nas procesor najniższego poziomu i sprawiają, że myślimy, że jednocześnie wykonujemy kod.
Te „rzeczy” mogą być procesami, które są jednostkami kodu uruchamianymi jednocześnie w tym sensie, że każdy proces myśli, że działa w swoim własnym świecie z własną, niewspółdzieloną pamięcią.
Innym przykładem są wątki, które są jednostkami kodu wewnątrz procesów, które również umożliwiają współbieżność.
Powodem, dla którego 4 procesy robocze będą w stanie obsłużyć więcej niż 4 żądania, jest to, że będą odpalać wątki, aby obsłużyć coraz więcej żądań.
Rzeczywisty limit żądań zależy od wybranego serwera HTTP, I / O, systemu operacyjnego, sprzętu, połączenia sieciowego itp.
Powodzenia!
* instrukcje to bardzo podstawowe polecenia, które może wykonać procesor. przykłady - dodaj dwie liczby, przeskocz z jednej instrukcji do drugiej
źródło