Piąty artykuł z cyklu Konfigurujemy VPS. Najwyższy czas napisać o serwerze WWW.
Mamy tu sytuację trochę podobną jak w przypadku DNS - jeden program (Apache) jest używany w zdecydowanej większości zastosowań i właściwie utożsamiany z serwerem WWW pod Linuxem (i nie tylko pod Linuxem). Jest o tyle inaczej, że ten program jest faktycznie fajny. Ale nie jedyny. A różnica w stosunku do nginxa czy lighttpd nie polega na wypieszczeniu kodu czy atrakcyjnych dodatkach, jest fundamentalna.
Koncepcja
Jak działa Apache (a także IIS i wiele innych serwerów WWW)? Każde nadchodzące żądanie jest przydzielane do jakiegoś procesu lub wątku roboczego, a ten zajmuje się odczytaniem treści żądania, pełną obsługą i odesłaniem wyniku. Przez cały ten czas proces lub wątek jest dedykowany do obsługi tego jednego żądania i niczym innym się nie zajmuje.
Nginx, lighttpd czy Cherokee działają inaczej. Jeden
proces monitoruje gromadę otwartych połączeń, reagując na możliwość
odczytu lub zapisu danych. Trochę więcej o takim stylu programowania
już pisałem, patrz artykuł o programowaniu zdarzeniowym.
Czemu jest to wielka różnica?
Przede wszystkim ze względu na radykalnie niższy koszt nawiązanego połączenia.
Przy wysycających testach w sieci lokalnej, gdy klienci nadają i odbierają żądania z dużą prędkością, różnica wydajności nie jest wielka (choć w większości benchmarków nginx i lighttpd pewną przewagę nad Apache uzyskują).
Prawdziwy skok następuje, gdy klienci są wolni. Gdy stronę czy obrazek ściąga człowiek używający modemu, przeciążonego łącza albo mieszkający na drugiej półkuli. W przypadku Apache każdy taki klient kosztuje dużo: zajmuje proces albo wątek.
Jeszcze drastyczniej wygląda to (nawet przy szybkich klientach) gdy są używane opcje keep-alive (utrzymywanie otwartego połączenia w celu pobrania wielu elementów jeden po drugim).
W przypadku nginxa kosztem połączenia z klientem jest otwarty socket i bufor z następną porcją danych. Dlatego można obsłużyć dużo więcej równoczesnych realnych połączeń.
Ma to znaczenie w bardzo dużych zastosowaniach (lighttpd proksujący youtube czy nginx w podobnym celu używany przez WordPress.com i Gravatar) ale i na VPS, gdzie nginx zużyje wielokrotnie mniej pamięci niż obsługujący porównywalny ruch Apache. Plus - pozwoli rozważać keep-alive jako realną opcję.
Reverse proxy
Tradycyjnym rozwiązaniem powyższego problemu dla Apache jest stosowanie reverse proxy. Przed głównym serwerem stawiamy dodatkowe, lekkie proxy, które bierze na siebie ciężar połączeń z klientami (w razie potrzeby, również SSL), kierując do głównego serwera czysty, szybki ruch. Szczególnie efektywne, gdy główny serwer jest gruby (powiedzmy, zawiera mod_perla, mod_php czy inny interpreter).
W roli reverse proxy serwery zdarzeniowe są szczególnie efektywne i warte rozważenia. Nawet na jednej maszynie. Zamiast stawiać samotne Apache, obetnijmy je nieco i postawmy przed nim zdarzeniowy serwer serwujący statyczne pliki i proksujący dynamiczny ruch.
Nginx
Do instalacji na VPS proponuję nginxa. Nie chcę tu prowadzić dyskusji o jego zaletach i wadach w porównaniu z innymi serwerami zdarzeniowymi (w szczególności, lighttpd także ma wielu zwolenników, po części ponieważ pojawiło się wcześniej). Nginxa używam od dwóch lat, zarówno na maluteńkim VPSie o 96MB RAM (który musiał dzielić z kilkoma innymi programami), jak na obecnym linode sprawuje mi się bardzo ładnie. Lubię składnię jego plików konfiguracyjnych, miejscami przyjemniejszą nawet od Apache.
Jeśli ktoś zna i lubi Apache - proszę używać. Na dzisiejszych, dość dużych VPSach, program ten spokojnie sobie radzi. Konfiguracji Apache szczegółowo opisywać tu nie będę, bo jest dostępna masa książek i serwisów na ten temat, o kilka uwag na temat przycinania go do niewielkiej ilości pamięci być może się w którymś z dalszych odcinków pokuszę.
Nawet konfiguracja w której używamy równocześnie i Nginxa (jako reverse-proxy i serwer statycznych plików) i Apache (jako kontener skryptów) nie jest bynajmniej absurdalna, nawet na małych maszynach.
Jeszcze drobne ciekawostki: autorem Nginxa jest rosyjski programista Igor Sysojew, znany wcześniej jako twórca kilku modułów optymalizujących wydajność pierwszej wersji Apache. Jednym z celów rozwijania programu było uzyskanie zadowalającej wydajności rosyjskiego portalu Rambler.
Nazwę nginx wymawiamy jak engine-X.
Instalacja Nginxa
Nginx jest już zwykle dostępny w paczkach, choć niektóre dystrybucje zawierają antyczną wersję. W chwili gdy piszę ten artykuł stabilną wersją jest 0.6.32, a eksperymentalną 0.7.19. W Ubuntu Hardy w paczce jest 0.5.33 (w Intrepid 0.6.32), które przynajmniej na początek wystarczy.
Autor stosuje nieco nietypową konwencję numeracyjną. Do niedawna wersją stabilną było 0.5. a eksperymentalną 0.6.. Po sekwencji releasów poprawiających usterki i dopracowywujących wprowadzone w linii 0.6 nowe funkcje wersja 0.6.30 została mianowana stabilną i pojawiła się rozwojowa linia 0.7.
Tedy:
$ sudo apt-get install nginx
(samodzielna kompilacja, gdyby ktoś się na nią zdecydował, też nie jest szczególnie problematyczna).
Uwaga: na Debianie i Ubuntu dość łatwo można niechcący zainstalować Apache (wiele pakietów ma ustawioną zależność od tego serwera, np. przy instalowaniu PHP czy paczkowanych aplikacji webowych Apache chce się instalować). Aby uniknąć przypadkowych problemów w przyszłości, można rozważyć ... zainstalowanie Apache i przekonfigurowanie go tak, by nie startował (a przede wszystkim, by nie zajmował portu 80). Na przykład:
$ sudo apt-get install apache2-mpm-prefork
$ sudo a2dissite default
i na doczepkę zakomentowanie Listen 80
w /etc/apache2/ports.conf
.
Absolutne minimum konfiguracji
Ten artykuł jest już dość długi, więc o konfiguracji nginxa napiszę
porządnie w kolejnym odcinku. W poinstalacyjnej konfiguracji, po poprawieniu
nazwy serwera (server_name
) w pliku
/etc/nginx/sites-available/default
, będzie serwował dokumenty z
drzewa poniżej /var/www/nginx-default
.