Tornado wykorzystuje asynchronous, non-blocking I/O rozwiązać the C10K problem. Oznacza to, że wszystkie operacje we/wy są sterowane zdarzeniami, to jest używają wywołań zwrotnych i powiadomienia o zdarzeniu, zamiast czekać na operację, aby powrócić. Node.js i Nginx używają podobnego modelu. Wyjątkiem jest tornado.database
, który jest blokowany. Model Tornado IOLoop source jest dobrze udokumentowany, jeśli chcesz przyjrzeć się szczegółom. Konkretny przykład znajduje się poniżej.
Nie blokujące i asynchroniczne są używane zamiennie w Tornado, chociaż w innych przypadkach występują różnice; this answer gives an excellent overview. Tornado używa jednego wątku i kolejno obsługuje żądania, aczkolwiek bardzo szybko, ponieważ nie czeka na IO. W produkcji zwykle uruchamiasz wiele procesów Tornado.
Jeśli chodzi o konkretny przykład, że masz żądanie HTTP, które Tornado musi pobrać niektórych danych (asynchronicznie) i reagowania, oto (z grubsza) co się dzieje:
- Tornado odbiera żądania i wywołuje odpowiednią metodę uchwytu w aplikacji
- Twoja metoda obsługi sprawia asynchronicznego połączenia z bazą danych, o oddzwonienie
- powraca połączeń bazy danych, funkcja zwrotna jest wywoływana, a odpowiedź zostanie wysłana.
Czym różni się Tornado (na przykład od Django), że pomiędzy etapem 2 a 3 proces może dalej obsługiwać inne żądania. Tornado IOLoop po prostu utrzymuje połączenie otwarte i kontynuuje przetwarzanie swojej kolejki wywołania zwrotnego, podczas gdy z Django (i dowolnym synchronicznym środowiskiem sieciowym) wątek zawiesza się, czekając na powrót bazy danych.
Dobrze napisana odpowiedź. Kiedy mówisz "powiadomienie o zdarzeniu", masz na myśli wygenerowane zdarzenia sygnalizujące zakończenie operacji wejścia/wyjścia, aby wywołania zwrotne? Czy są jakieś inne rodzaje wydarzeń? Dzięki! – skyork
Tak, chodzi mi o to, że Tornado jest powiadamiane o przychodzących danych przez epoll lub kqueue, czyli powiadomienia o zmianach sterowanych za pomocą krawędzi. –