Nie ma srebrnej kuli
W praktyce zależy to ...
tl; dr - łatwe rozwiązanie, użyj nginx ...
Bloking:
Na przykład Apache domyślnie stosuje schemat blokowania, w którym proces jest rozwidlany dla każdego połączenia. Oznacza to, że każde połączenie potrzebuje własnej przestrzeni pamięci, a sama liczba narzutów związanych z przełączaniem kontekstu wzrasta wraz ze wzrostem liczby połączeń. Ale zaletą jest to, że po zamknięciu połączenia kontekst może zostać zlikwidowany, a dowolną / całą pamięć można łatwo odzyskać.
Podejście wielowątkowe byłoby podobne, ponieważ narzut związany z przełączaniem kontekstu rośnie wraz z liczbą połączeń, ale może być bardziej wydajny pod względem pamięci w kontekście współużytkowanym. Problem z takim podejściem polega na tym, że zarządzanie pamięcią współużytkowaną w bezpieczny sposób jest trudne. Podejścia do przezwyciężania problemów z synchronizacją pamięci często obejmują własny narzut, na przykład blokowanie może zamrozić główny wątek przy obciążeniach intensywnie obciążających procesor, a użycie niezmiennych typów dodaje dużo niepotrzebnego kopiowania danych.
AFAIK, stosowanie podejścia wieloprocesowego na blokującym serwerze HTTP jest ogólnie preferowane, ponieważ zarządzanie / odzyskiwanie pamięci jest bezpieczniejsze / prostsze w bezpieczny sposób. Odśmiecanie staje się problemem, gdy odzyskiwanie pamięci jest tak proste, jak zatrzymanie procesu. W przypadku długotrwałych procesów (np. Demona) ta cecha jest szczególnie ważna.
Podczas gdy narzut związany z przełączaniem kontekstu może wydawać się nieistotny w przypadku niewielkiej liczby pracowników, wady stają się bardziej istotne, gdy obciążenie skaluje się do setek do tysięcy równoczesnych połączeń. W najlepszym wypadku przełączanie kontekstu skaluje O (n) do liczby obecnych pracowników, ale w praktyce najprawdopodobniej jest gorzej.
Tam, gdzie serwery wykorzystujące blokowanie mogą nie być idealnym wyborem dla dużych obciążeń We / Wy, są one idealne do pracy wymagającej dużej mocy procesora, a przekazywanie wiadomości jest utrzymywane na minimalnym poziomie.
Nieblokujący:
Nieblokowanie byłoby czymś w rodzaju Node.js lub nginx. Są one szczególnie znane ze skalowania do znacznie większej liczby połączeń na węzeł pod obciążeniem intensywnym we / wy. Zasadniczo, gdy ludzie osiągną górną granicę, jaką serwery oparte na wątkach / procesach mogą obsłużyć, zaczęli szukać alternatywnych opcji. Jest to również znane jako problem C10K (tj. Zdolność do obsługi 10 000 jednoczesnych połączeń).
Nieblokujące serwery asynchroniczne mają zwykle wiele cech charakterystycznych dla podejścia wielowątkowego z blokowaniem, polegające na tym, że należy uważać, aby uniknąć obciążeń intensywnie wykorzystujących procesor, ponieważ nie chcemy przeciążać głównego wątku. Zaletą jest to, że narzut związany z przełączaniem kontekstu jest zasadniczo wyeliminowany, a przekazanie komunikatu kontekstowego staje się nieproblemowe.
Chociaż może nie działać w przypadku wielu protokołów sieciowych, bezstanowa natura HTTPs działa szczególnie dobrze w przypadku architektur nieblokujących. Dzięki kombinacji odwrotnego proxy i wielu nieblokujących serwerów HTTP możliwe jest identyfikowanie i trasowanie wokół węzłów doświadczających dużego obciążenia.
Nawet na serwerze, który ma tylko jeden węzeł, bardzo często konfiguracja obejmuje jeden serwer na rdzeń procesora, aby zmaksymalizować przepustowość.
Obie:
„Idealny” przypadek użycia byłby kombinacją obu. Odwrotny serwer proxy z przodu poświęcony żądaniom routingu u góry, a następnie połączenie serwerów blokujących i nieblokujących. Nie blokuje zadań IO, takich jak serwowanie treści statycznych, zawartości pamięci podręcznej, treści HTML. Blokowanie zadań obciążających procesor, takich jak kodowanie obrazów / wideo, przesyłanie strumieniowe treści, dzielenie numerów, zapisywanie w bazie danych itp.
W Twoim przypadku:
Jeśli po prostu sprawdzasz nagłówki, ale nie przetwarzasz żądań, to zasadniczo to, co zasadniczo opisujesz, to zwrotny serwer proxy. W takim przypadku zdecydowanie wybrałbym podejście asynchroniczne.
Sugerowałbym przejrzenie dokumentacji wbudowanego odwrotnego proxy nginx .
Na bok:
Przeczytałem ten zapis z linka, który podałeś i ma sens, że async był kiepskim wyborem dla ich konkretnej implementacji. Problem można podsumować w jednym stwierdzeniu.
Stwierdzono, że podczas przełączania między klientami kod do zapisywania i przywracania wartości / stanu był trudny
Budowali państwową platformę. W takim przypadku podejście asynchroniczne oznaczałoby, że będziesz musiał stale zapisywać / ładować stan za każdym razem, gdy zmienia się kontekst (tj. Po uruchomieniu zdarzenia). Ponadto po stronie SMTP wykonują dużo pracy wymagającej dużej mocy obliczeniowej.
Wygląda na to, że mieli dość słabą znajomość asynchronizacji, w wyniku czego przyjęli wiele złych założeń.