Konfiguracja Nginx dla treści statycznych

W notce Prosty CDN Zend opisałem jak zaimplementować dostarczanie treści z wielu domen dla naszej strony w kodzie Zend. Kiedy już strona jest przygotowana programistycznie, należy stworzyć konfiguracje  serwera www dla dostarczania treści statycznych, można to zrobić wykorzystując np. Nginx

Elementy statyczne dla naszej strony (pliki graficzne, css, javascript) może z powodzeniem dostarczać jakiś lekki serwer www. Nie ma sensu zaprzęgać do tego zadania apache. W zarządzanej przeze mnie infrastrukturze wykorzystuję do tego Nginx, którego dość przyjemnie konfiguruje się pod tym kątem.

Stosowany przeze mnie na codzień schemat uwzględnia także load – balancing dla dostarczania elementów statycznych (do tematu load – balancingu może jeszcze wrócę 😉 ), jednak tutaj chciałem skupić się tylko bezpośrednio na ustawieniu „końcowych” serwerów dostarczających pliki. Oczywiście wszystkie ustawienia mają na celu jak najszybsze dostarczanie treści statycznych oraz robienie tego zgodnie z wytycznymi SEO.

Nasze przygotowania zacząć należy od tego, że treści statyczne dobrze dostarczać z innej domeny, niż dynamiczne treści na stronie. Dlaczego? Jest to jeden z wymogów SEO (brany pod uwagę m.in. w cenie Yahoo), ale takie działanie ma też znaczenie praktyczne – ogranicza ilość przesyłanych danych i przyspiesza ich dostarczanie. Sytuacja ta wynika z faktu, iż wszelkiego rodzaju pliki cookies ustawione dla domeny nadrzędnej zostaną przekazane subdomenom. W związku z tym treści serwowane przez domenę img.domain.com otrzymają wszystkie ciastka, które generuje domain.com. W skrajnych przypadkach wielkość cookies może być równa lub większa od wielkości przesyłanego pliku. Dlatego dostarczamy pliki statyczne przez domenę nie generującą cookies.

Rzeczą niezwykle istotną dla szybkiego dostarczania plików (w ogóle) jest ich rozmiar. W poprzednim akapicie opisano jeden z kroków do sumarycznego ograniczenia wielkości wysyłanych danych, kolejnym sposobem jest włączenie kompresji gzip.

W mojej infrastrukturze korzystam z kompresji gzip w locie, Nginx oferuje również pre-kompresję i jest to rozwiązanie dobre przy olbrzymim ruchu na stronie lub niewielkich zasobach maszyny (pre-kompresja ogranicza użycie procesora i RAM). Na potrzeby małych i średnich stron WWW (lub nawet większych przy wydajnej maszynie) wystarczy zastosować kompresję w locie i na tym się skupię.

Nginx moduł gzip uaktywnia się poprzez dodanie linijki:

gzip on;

w sekcji httpserver lub location konfiguracji (przy tworzeniu osobnych konfiguracji dla serwerów treści statycznych najwygodniej włączyć kompresję w sekcji server). Teraz rozszerzamy konfigurację gzip o kilka dodatkowych zmiennych:

gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/xml application/x-javascript application/javascript text/css;
gzip_comp_level 1;
gzip_disable "msie6";
gzip_vary  on;
gzip_http_version 1.1;

powyższa konfiguracja ustawia kompresję dla plików tekstowych m.in. z wyłączeniem kompresji dla Internet Explorer 6 (więcej zmiennych oraz ich opis znajduje się w dokumentacji serwera www).

Kolejną rzeczą, o którą powinniśmy zadbać są odpowiednie nagłówki wysyłane wraz z treściami statycznymi – głównie nagłówki kontroli cache oraz wygasania. Te pierwsze ustawia się w następujący sposób:

add_header Cache-Control private;

te drugie tak:

expires modified +7d;

oba nagłówki odpowiadają za obsługę plików statycznych po stronie klienta. Pierwszy definiuje tryb obsługi cache, drugi zaś określa czas, przez jaki po stronie klienta „ważne” są pobrane pliki statyczne. Oczywiście, samej metodologii ustawiania nagłówków expires można poświęcić osobny wpis – chwilowo wszystkich zainteresowanych zgłębieniem tematu zapraszam do dokumentacji Nginx.

Kiedy już zadbamy o odpowiednie dostarczanie treści pora na kilka kroków optymalizacyjnych po stronie serwera. Pierwszy krok wydaje się banalnie prosty, ale może okazać się istotnym drobiazgiem, chodzi o „okiełznanie” raportowania działań serwera. Poziom logowania aktywności serwera również wpływa na jego obciążenie, ponieważ w przypadku treści statycznych można zrezygnować z logowania dostępu oraz ograniczyć logowanie błędów (interesują nas tak na prawdę jedynie najpoważniejsze błędy)  powinniśmy zrobić to tak:

access_log off;
error_log  error.log crit;

ustawienie to wyłączy logowanie dostępu oraz ograniczy logowanie błędów wyłącznie do tych krytycznych.

Kolejnym krokiem przyspieszającym działanie serwera jest włączenie cache dla otwartych plików:

 open_file_cache max=2000 inactive=20s;

jest to funkcjonalność Nginx, która pozwala przechowywać w pamięci meta dane o plikach (rozmiar, czas modyfikacji itd.).  Szczegółowy opis opcji konfiguracyjnych można znaleźć tutaj.

Przygotowanie konfiguracji wg tych wytycznych pozwoli na stworzeni wydajnego serwera dla treści statycznych. Wszystkie wymienione wyżej opcje można stosować w sekcji server (czyli dla pojedynczej domeny), a część z nich nawet w sekcji location konfiguracji.

Na koniec hint leniwego informatyka 😉 Konfiguracja domen dla treści statycznych może wskazywać na ten sam katalog, co właściwa strona (pozwala to uniknąć kopiowania treści statycznych w inne miejsce, czy też precyzyjnego dobierania ścieżek dosepu), aby uniknąć duplicated content, czyli wykonywania plików skryptów czy dostępu do plików html wystarczy dodać odpowiedni warunek w sekcji location :

location / {
         if ($request_filename ~ "\.(jpg|gif|png|swf|ico|mp3)$") {
                break;
        }

        return 404;
}

dzięki temu system zwróci kod 404 w przypadku dostępu do pliku innego niż rozszerzenie wymienione w wyrażeniu regularnym.

Poniżej do pobrania szkielet przykładowej konfiguracji server zbudowanej wg powyższych wytycznych.

Mikołaj Niedbała

I'm a Poland based IT administrator, linux administrator and IT engineer creating professional IT infrastructure solutions based on Linux and virtual environments.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *