Nginx serwer www z obsługą php@FastCGI part I

nginx

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 prodykcyjnym 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 sprzetu) ,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ęde 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:
  • user www-data; - konfiguracja z jakimi prawami będzie uruchomiony serwer
  • worker_processes 1; - ilość uruchomionych procesów, tutaj kierować się należy zasadą: ilość rdzeni = ilość procesów (jeżeli jest taka potzreba)
  • worker_connections 1024; - maksymalna ilość połączeń w ramach 1 procesu
    Dzięki dwóm powyższym parametrom teoretycznie możemy oszacować maksmalną 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 jescze bezpieczniej przez 4.
  • include - cała konfigurację można umieścić w pliku nginx.conf ale dla większej przejrzystości i porządku, szczególnie jesli jest ona rozbudowana (np. wiele domen) można umieszczać w osobnych plikach.
  • W Debianie i pokrewnych dystrybucjach model rozmieszczenia plików jest zapożyczony z Apache (katalogi: sites-available , sites-enabled).
    Trzymając się konwencji Debiana dodatkową konfigurację oddeleguję do osobnych plików.
  • Nginx serwujący kontent statyczny:
  • stworzmy w /etc/nginx/sites-available plik example a w nim:
  • 
    server {
    	# Dyrektywa okreslają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;    
    		}  
    
    }
    
  • teraz tworzymy dowiązanie symboliczne: ln -s /etc/nginx/sites-available/przyklad /etc/nginx/sites-enabled/przyklad
  • następnie restart nginx-a: /etc/inid.d/nginx restart
  • Jeśli nie mamy domeny nie uzywamy wtedy dyrektywy server_name, jeżeli jednak chcemy mieć kilka stron na jednym IP możemy wystawić je na różnych portach:
    
    # 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 sie na dość kłopotkiwą sytuacje. Przedstawie 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 nastomiast 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śći nginx-a, nic nie wspomniałem o konfiguracj reverse-proxy czy silnemu wsparciu wyrażeń regularnych...
  • Nginx z obsługa PHP poprzez FastCGI part II

Powrót »