2009-05-26 9 views
9

Serwery sieci Web, takie jak lighttpd lub nginx, są dostępne w postaci nie-rozwidlonej lub select(), zyskując coraz większą popularność.Jak działa serwer WWW, który nie jest rozwidleniem?

Chociaż istnieje wiele dokumentów wyjaśniających rozwidlające się serwery (na różnych poziomach szczegółowości), dokumentacja dla serwerów niezwiązanych z rozwidleniem jest niewielka.

ja szukam ptasie oczy widzenia jaknon-rozwidlone serwer internetowy działa. (Pseudo-) lub diagram stanu maszyny, rozebrany do minimum , byłby świetny.

Jestem świadomy następujących zasobów i uznałem je za pomocne.

Jednak jestem zainteresowany zasadami, a nie szczegóły implementacji.

Konkretnie:

  • Dlaczego ten typ serwera czasami nazywane non-blokowanie, kiedy select() zasadniczo blokuje?

  • Przetwarzanie żądania może zająć trochę czasu. Co dzieje się z nowymi żądaniami w tym czasie, gdy nie ma określonego wątku lub procesu? Czy przetwarzanie żądań zostało w jakiś sposób przerwane lub czas został przerwany?

Edit: Jak rozumiem, podczas gdy wniosek jest przetwarzany (na przykład plik odczytać lub uruchomić skrypt CGI) serwer nie akceptuje nowych połączeń. Czy nie oznacza to, że taki serwer może nie mieć wielu nowych połączeń, jeśli skrypt CGI działa, powiedzmy, 2 sekundy?

+1

myślałem, że zakaz rozwidlone serwer WWW byłby zły mecz na dowolnym serwerze WWW, który chciał się z serwerem więcej niż trywialny ilości dynamicznej zawartości . – Eddie

+0

@Ddie Co najmniej. W przypadku n procesorów, posiadanie więcej niż n wątków nie pozwoli ci wykonać więcej pracy. Odpowiednio zaprojektowany serwer asynchroniczny może wykonywać tak samo dużo pracy, jak rozwidlanie lub gwintowanie. –

+0

@Nick Johnson: To zależy. Jeśli masz N procesorów i N wątków, do tego stopnia, że ​​jedno z żądań blokuje oczekiwanie na I/O, w rzeczywistości nie używasz procesora, chyba że utworzysz więcej wątków. Na przykład, jeśli musisz przejść do bazy danych, aby spełnić żądanie dynamiczne, wątek zostanie zatrzymany do momentu otrzymania odpowiedzi. Mając tylko N wątków, możesz spędzić większość czasu na oczekiwaniu i tylko niewielką część czasu na przetwarzanie. – Eddie

Odpowiedz

8

Podstawowe pseudokod:

setup 
while true 
    select/poll/kqueue 
    with fd needing action do 
     read/write fd 
     if fd was read and well formed request in buffer 
      service request 
     other stuff 
  • Choć select() & znajomych blokowania, gniazdo I/O nie blokuje. Jesteś zablokowany dopiero, gdy będziesz miał coś fajnego do roboty.
  • Przetwarzanie pojedynczych żądań zwykle wymaga odczytywania deskryptora pliku z pliku (zasoby statyczne) lub procesu (zasób dynamiczny), a następnie zapisywania w gnieździe. Można to zrobić wygodnie, nie zachowując zbyt wiele stanu.
  • Tak więc powyżej oznacza zazwyczaj otwarcie pliku, dodanie go do listy dla select i odnotowanie, że rzeczy z niego odczytane wychodzą do określonego gniazda. W razie potrzeby zamień FastCGI na plik.

EDIT:

  • Nie wiem o innych, ale nginx ma 2 procesy: mistrza i robotnika. Mistrz nasłuchuje, a następnie przekazuje zaakceptowane połączenie do pracownika w celu przetworzenia.
4

select() PLUS powodują blokowania I/O zasadniczo pozwala na zarządzanie/odpowiedzi na wiele połączeń, ponieważ pochodzą one w jednym wątku (multipleksowania), w porównaniu posiadające wiele wątków/procesów obsłużyć jedno gniazdo każdy. Celem jest zminimalizowanie stosunku śladu serwera do liczby połączeń.

Jest wydajny, ponieważ ten pojedynczy wątek wykorzystuje wysoki poziom aktywnych połączeń gniazd wymaganych do osiągnięcia nasycenia (ponieważ możemy wykonywać niezablokowane operacje we/wy na wiele deskryptorów plików).

Uzasadnieniem jest to, że uzyskanie bajtów jest bardzo czasochłonne, zinterpretowanie ich, a następnie wybór odpowiednich bajtów do umieszczenia w strumieniu wyjściowym. Rzeczywiste operacje we/wy są obsługiwane bez blokowania tego wątku serwera.

Ten typ serwera zawsze czeka na połączenie, blokując przy wyborze(). Po uzyskaniu jednego, obsługuje połączenie, a następnie wraca do select() w nieskończonej pętli. W najprostszym przypadku ten wątek serwera NIE blokuje żadnego innego czasu poza tym, gdy konfiguruje wejścia/wyjścia.

Jeśli pojawi się drugie połączenie, zostanie ono obsłużone następnym razem, gdy serwer wybierze(). W tym momencie nadal może być odbierane pierwsze połączenie i możemy rozpocząć wysyłanie do drugiego połączenia z tego samego wątku serwera. To jest cel.

Wyszukaj "multiplexing network sockets", aby uzyskać dodatkowe zasoby.

Lub spróbuj UNIX Programming sieci przez Stevensa, Fenner, Rudoff