Nginx serwer www z obsługą php@FastCGI part I
Nginx to lekki serwer http i reverse proxy. Potrafi także działać jako load balancer, dlatego często określany jest jako router HTTP.
Stanowi poważną alternatywę dla przeładowanego apache. W środowisku produkcyjnym nginx zaskakuje wydajnością oraz małym zużyciem pamięci co jest zaletą dla dużych jak wordpress.com jak i małych jak słabiutki vps z 128MB.
Na niekorzyść nginx-a przemawia fakt, braku wsparcia plików .htaccess oraz składnia modułu rewrite jest nieco inna od składni mod_rewrite.
Brak obsługi .htaccess determinuje konieczność wprowadzania czy to dyrektyw rewrite czy innych obsługiwanych w .htaccess do konfiguracji serwera przez jego administratora.
Przewagę jaką uzyskuje nginx nad popularnym apachem wynika z modelu obsługi przychodzących połączeń. W Apache każde nowe połączenie wymaga
uruchomienia nowego procesu (mpm-prefork) lub wątku (mpm-worker), który obsłuży przychodzące żądanie.
W przypadku nginx-a mamy do czynienia z modelem zdarzeniowym polegającym na obsłudze wielu połączeń przez ten sam proces, który reaguje na takie zdarzenia, jak nowe żądanie od klienta,
odpowiedź od serwera aplikacji itp. Jeżeli na jednym połączeniu nic się nie dzieje, proces nginxa może obsługiwać inne, aktywne połączenie. Proces (wątek) Apache'a czeka wtedy bezczynnie.
Nginx tworzy 1-n... procesów (w zależności od potrzeb i sprzętu), każdy z tych procesów, może obsłużyć kilkadziesiąt/set tysięcy połączeń.
Pokrótce tyle teorii.
Na początku chcę zaznaczyć, iż nie będę się wdawał w sam proces instalowania nginx-a, wiadomo to już jest uzależnione od dystrybucji (paczki) lub indywidulanej konfiguracji (kompilacji ze źródeł).
- Globalna konfiguracja serwera:
- główny plik konfiguracyjny - nginx.conf
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
i krótki opis do tego pliku:
Dzięki dwóm powyższym parametrom teoretycznie możemy oszacować maksymalną liczbę równocześnie obsłużonych klientów: max_clients = worker_processes * worker_connections , natomiast trzeba pamiętać, że w przypadku serwowania stron dynamicznych np. w php jeden klient otwiera dwa połączenia (FastCGI), i już wtedy: max_clients = worker_processes * worker_connections / 2
a jeszcze bezpieczniej przez 4.
server {
# Dyrektywa określająca adres i/lub port, na których serwer nasłuchuje
listen 80;
# Dyrektywa przypisująca nazwy wirtualnym serwerom
server_name przyklad.pl www.przyklad.pl;
# Logi domeny przyklad.pl
access_log /var/log/nginx/przyklad.access.log;
error_log /var/log/nginx/przyklad.pl.error.log;
location / {
root ścieżka naszego katalogu ze stroną;
index index.html index.htm;
}
}
# strona_1:
server {
listen 80;
# ....
location / {
root /var/www/strona_1;
index index.html index.htm;
}
}
# strona_2:
server {
listen 81;
# ....
location / {
root /var/www/strona_2;
index index.html index.htm;
}
}
W czasie konfiguracji nginx-a natknąłem się na dość kłopotliwą sytuacje. Przedstawię ją na konkretnym przykładzie:
Wyobraźmy sobie, że mamy domenę example.com, 4 subdomeny: main.example.com, poczta.example.com, users.example.com, qwerty.example.com .
Trzy pierwsze są wirtualnymi hostami wykorzystywanymi przez nginx-a natomiast ostania qwerty.example.com nie jest powiązana z żadną
konfiguracją wirtualnego hosta. I tu pojawia się problem, gdyż kiedy wpiszemy w przeglądarkę http://qwerty.example.com/ - wtedy wyswietli nam się
jedna z tych trzech stron (chyba zależy od kolejności jaką nginx robi include).
W pliku nginx.conf wstawiamy blok server przed dyrektywami include:
server {
listen 80 default;
server_name _ ; # Catch all
return 444; # Kod 444 zamyka połączenie bez wysyłania nagłówków.
}
Oczywiście jest to ułamek możliwości nginx-a, nic nie wspomniałem o konfiguracj reverse-proxy czy silnemu wsparciu wyrażeń regularnych...