Kariera
Blog
Kontakt

Dlaczego kolejna wtyczka nie naprawi wolnej strony?

Architektura Varnish Cache w ISPConfig 3 z Nginx SSL, Apache, WordPressem i Craft CMS

Wolna strona internetowa nie zawsze potrzebuje kolejnej wtyczki optymalizacyjnej. Czasem problem znajduje się głębiej: w konfiguracji serwera, warstwie cache albo sposobie, w jaki ruch przechodzi między Nginxem, Apache i aplikacją.

W jednym z projektów uporządkowałem architekturę środowiska opartego na ISPConfig 3. Celem było dodanie Varnish Cache przed Apache, przy zachowaniu terminacji SSL w Nginxie oraz poprawnej obsługi stron opartych na WordPressie i Craft CMS.

Jak wygląda przepływ ruchu

W praktyce przepływ wygląda tak:

Przepływ ruchu HTTPS w ISPConfig 3 przez Nginx SSL, Varnish Cache, Apache oraz WordPress lub Craft CMS

Przepływ ruchu HTTPS w środowisku ISPConfig 3: Internet → Nginx SSL → Varnish Cache → Apache → WordPress lub Craft CMS.

Infografika do artykułu technicznego na potacki.com. Pokazuje prosty przepływ ruchu w architekturze wykorzystującej Nginx, Varnish Cache, Apache oraz aplikację opartą na WordPressie lub Craft CMS. Nginx odpowiada za obsługę HTTPS i przekazanie żądania dalej. Varnish zwraca gotową odpowiedź z cache, jeśli jest dostępna. Apache obsługuje backend aplikacji, a CMS generuje treść, gdy odpowiedź nie została jeszcze zapisana w cache'u.

Każda warstwa ma inne zadanie.

Nginx obsługuje HTTPS

Nginx przyjmuje ruch przychodzący po HTTPS, odpowiada za terminację SSL i przekazuje żądanie dalej. Dzięki temu Varnish nie musi samodzielnie obsługiwać certyfikatów.

Varnish zwraca gotową odpowiedź z cache

Jeżeli strona została wcześniej wygenerowana i może być bezpiecznie przechowywana, Varnish zwraca gotową odpowiedź bez uruchamiania aplikacji.

W praktyce oznacza to mniej zapytań docierających do Apache, PHP i bazy danych.

Apache obsługuje backend aplikacji

Jeżeli Varnish nie ma jeszcze gotowej odpowiedzi albo strona nie powinna zostać zapisana w cache, żądanie trafia do Apache.

Dopiero wtedy uruchamiany jest backend aplikacji.

WordPress lub Craft CMS generują treść

WordPress albo Craft CMS przygotowują odpowiedź HTML wtedy, gdy nie ma jej jeszcze w cache albo gdy dana strona musi pozostać dynamiczna.

Po wygenerowaniu publicznej strony odpowiedź może zostać ponownie zapisana i wykorzystana przy kolejnych wejściach.

Preload cache z mapy strony i dodatkowa warstwa Cloudflare

Wtyczka CDN Cache & Preload dla Craft CMS potrafi rozgrzewać cache na podstawie mapy strony XML. Po wyczyszczeniu pamięci podręcznej pobiera kolejne adresy z sitemapy i odbudowuje gotowe odpowiedzi HTML w warstwie cache.

Dzięki temu pierwsza osoba odwiedzająca podstronę nie musi czekać, aż aplikacja ponownie wygeneruje całą odpowiedź.

Podobny mechanizm preloadu jest dostępny również w popularnych rozwiązaniach dla WordPressa, takich jak WP Rocket czy FlyingPress. Sama zasada jest prosta: zamiast czekać na przypadkowe wejścia użytkowników, system sam przechodzi po najważniejszych adresach i przygotowuje cache wcześniej.

Jeżeli przed serwerem działa dodatkowo Cloudflare, można dodać kolejną warstwę cache. Wymaga to jednak odpowiednich reguł, ponieważ Cloudflare domyślnie nie przechowuje stron HTML.

Po poprawnej konfiguracji gotowe odpowiedzi mogą być serwowane bliżej użytkownika, a część ruchu nie musi docierać do aplikacji, PHP ani bazy danych.

Taka architektura dobrze radzi sobie zarówno ze zwykłym ruchem, jak i z krótkimi skokami obciążenia. Nie wystarczy jednak włączyć kilka mechanizmów i uznać temat za zamknięty.

Cache powinien przyspieszać strony publiczne, ale nie może obejmować miejsc zależnych od sesji użytkownika, koszyka, formularzy ani panelu administracyjnego.

Trzeba ustalić, które adresy można bezpiecznie przechowywać, kiedy je odświeżać i w jaki sposób usuwać stare wersje po zmianie treści.

Preload cache z mapy strony XML, Varnish Cache i dodatkową warstwą Cloudflare

Zobacz plugin CDN Cache & Preload dla Craft CMS

Najczęstsze problemy z cache w praktyce

Samo uruchomienie Varnisha, Cloudflare albo wtyczki cache nie oznacza jeszcze, że architektura działa poprawnie.

Najwięcej problemów pojawia się wtedy, gdy poszczególne warstwy nie wiedzą, kiedy zapisać odpowiedź, kiedy ją pominąć i kiedy usunąć starą wersję strony.

Brak poprawnego purge po zmianie treści

Pierwszy problem pojawia się po edycji wpisu, strony albo produktu. Jeżeli cache nie zostanie poprawnie wyczyszczony, użytkownik nadal może zobaczyć starą wersję treści.

W prostym środowisku wystarczy usunąć jeden zapisany wariant strony. Przy kilku warstwach sytuacja jest bardziej złożona. Stara odpowiedź może nadal znajdować się w Varnishu, Cloudflare albo lokalnym cache’u aplikacji.

Dlatego purge powinien obejmować nie tylko pojedynczy adres URL, ale też powiązane miejsca.

Po aktualizacji wpisu warto odświeżyć:

  • stronę wpisu
  • stronę kategorii
  • listing bloga
  • stronę główną
  • inne widoki, na których pojawia się zmieniona treść

W bardziej rozbudowanych projektach lepiej myśleć o purge jako o procesie, a nie pojedynczym poleceniu.

Cache’owanie stron, które powinny pozostać dynamiczne

Nie każda strona może zostać zapisana jako gotowy HTML. Problem pojawia się wtedy, gdy cache obejmie widoki zależne od użytkownika.

Dotyczy to między innymi:

  • koszyka
  • formularza zamówienia
  • panelu użytkownika
  • wyników wyszukiwania
  • stron z indywidualnymi komunikatami
  • panelu administracyjnego
  • adresów z parametrami GET

Jeżeli taka strona trafi do cache’u, użytkownik może zobaczyć dane przygotowane dla innej sesji albo nieaktualny stan koszyka.

Dlatego reguły cache powinny jasno rozdzielać strony publiczne od miejsc dynamicznych.

Dobrze skonfigurowany system nie próbuje cache’ować wszystkiego. Przechowuje tylko to, co rzeczywiście można bezpiecznie współdzielić pomiędzy użytkownikami.

Cookies wyłączające cache dla zbyt dużej liczby użytkowników

Częstym problemem są również cookies. Wiele konfiguracji omija cache, gdy tylko w żądaniu pojawi się określone ciasteczko.

To ma sens w przypadku zalogowanych użytkowników albo koszyka WooCommerce. Problem zaczyna się wtedy, gdy cache jest wyłączany również przez cookies analityczne, marketingowe albo techniczne, które nie wpływają na zawartość strony.

W efekcie Varnish zaczyna przekazywać dużą część ruchu dalej do Apache i PHP, mimo że użytkownicy otrzymują dokładnie tę samą treść.

Warto więc sprawdzić, które cookies rzeczywiście wymagają pominięcia cache, a które można bezpiecznie ignorować.

Im prostsze i bardziej świadome reguły, tym większa liczba odpowiedzi może być zwracana bez obciążania backendu.

Błędne nagłówki Cache-Control

Nagłówki HTTP decydują o tym, jak długo odpowiedź może być przechowywana i kto może z niej korzystać.

Błędne ustawienie Cache-Control potrafi całkowicie zablokować działanie cache albo zrobić coś odwrotnego: pozwolić na przechowywanie treści, które powinny pozostać prywatne.

Najważniejsze różnice dotyczą dyrektyw takich jak:

public
private
no-cache
no-store
max-age
s-maxage

Dla publicznych stron warto używać reguł, które pozwalają warstwie pośredniej przechowywać odpowiedź.

Dla panelu użytkownika, koszyka i formularzy potrzebne są znacznie ostrożniejsze ustawienia.

Nie warto kopiować tych samych nagłówków dla całej strony. Lepszy efekt daje rozdzielenie odpowiedzi publicznych, prywatnych i dynamicznych.

Niepotrzebne zapytania dochodzące do Apache i PHP

Największą korzyścią z Varnisha jest to, że gotowa odpowiedź może zostać zwrócona bez uruchamiania aplikacji.

Jeżeli jednak reguły cache są zbyt zachowawcze albo niespójne, każde żądanie nadal trafia do Apache, PHP i bazy danych.

Wtedy serwer wykonuje dokładnie tę samą pracę wiele razy, mimo że wynik mógłby zostać zapisany wcześniej.

Warto obserwować, ile odpowiedzi kończy się jako HIT, a ile jako MISS, PASS albo BYPASS.

HIT
odpowiedź została zwrócona z cache

MISS
brakuje gotowej wersji i backend musi ją wygenerować

PASS lub BYPASS
cache został świadomie pominięty

Pojedyncze pominięcia są normalne. Problem pojawia się wtedy, gdy większość publicznego ruchu nadal dochodzi do Apache i PHP.

Cache powinien działać przewidywalnie

Dobrze skonfigurowany cache nie polega na przechowywaniu jak największej liczby stron.

Publiczne strony powinny być szybko zwracane w gotowym HTML. Widoki dynamiczne muszą pozostać poza cache. Zmiana treści powinna uruchamiać purge i ponowne rozgrzanie najważniejszych adresów.

Cookies nie powinny niepotrzebnie wyłączać cache dla anonimowych użytkowników.

Dopiero takie podejście realnie ogranicza liczbę zapytań trafiających do Apache, PHP i bazy danych.

Jak sprawdzić, czy cache faktycznie działa

Najprostszy test polega na porównaniu kilku kolejnych odpowiedzi dla tego samego adresu URL.

Pierwsze wejście może wygenerować MISS, ponieważ strona nie znajduje się jeszcze w pamięci podręcznej. Kolejne powinny już zwracać HIT.

Warto też obserwować czas odpowiedzi, nagłówki HTTP oraz logi Varnisha.

Sam dobry wynik w narzędziu do testowania wydajności nie zawsze wystarcza. Cache powinien działać stabilnie również po aktualizacji treści, zmianie plików CSS i JavaScript oraz przy wejściach anonimowych użytkowników z różnymi cookies.

Najlepsza konfiguracja cache to nie ta, która przechowuje wszystko.

Najlepsza jest ta, która wie, co można bezpiecznie zapisać, kiedy to usunąć i jak ograniczyć pracę backendu bez ryzyka pokazania użytkownikowi niewłaściwej treści.

Zobacz powiązane realizacje

Zobacz case study: Varnish Cache dla ISPConfig 3 z Nginx SSL Termination

Zobacz pozostałe projekty Linux, DevOps i wydajnościowe

magnifiercrosschevron-left