...

Porównanie handlerów PHP: wpływ na wydajność hostingu internetowego

To porównanie modułów obsługi PHP pokazuje, jak mod_php, CGI, FastCGI, PHP-FPM i LSAPI Wydajność wpływają na Twoje hostowanie – od obciążenia procesora po opóźnienia ogona. Wyjaśniam konkretnie, jaki wybór w przypadku WordPress, WooCommerce i szczytów ruchu Czas załadunku obniża zużycie energii, a jednocześnie oszczędza zasoby.

Punkty centralne

  • PHP-FPM skaluje się bardziej efektywnie niż mod_php i FastCGI.
  • LSAPI zapewnia najlepsze wyniki w LiteSpeed.
  • Izolacja na użytkownika zwiększa bezpieczeństwo.
  • OPcache i Redis zmniejszają opóźnienia.
  • P95/P99 pokazuje prawdziwe doświadczenia użytkowników.

Jak działają moduły PHP

Obsługa PHP łączy serwer WWW z interpreterem i steruje Procesy, pamięć i operacje wejścia/wyjścia dla każdego żądania. CGI uruchamia nowy proces dla każdego żądania i ponownie ładuje konfiguracje, co powoduje obciążenie i zwiększa Opóźnienie zwiększona. Nowoczesne warianty, takie jak FastCGI, PHP-FPM lub LSAPI, utrzymują pracowników w stanie ciągłej gotowości, oszczędzając w ten sposób czas uruchamiania, zmiany kontekstu i cykle procesora. OPcache pozostaje w pamięci, dzięki czemu nie trzeba za każdym razem kompilować kodu bajtowego, a strony dynamiczne reagują szybciej. Jednocześnie zarządzanie procesami decyduje o tym, ile jednoczesnych żądań może być obsługiwanych, jak ustalane są priorytety i jak można złagodzić szczyty obciążenia.

Bezpośrednie porównanie popularnych handlerów

Wybór operatora determinuje Skalowanie, model bezpieczeństwa i wymagania aplikacji dotyczące pamięci RAM. mod_php integruje PHP z procesem Apache i zapewnia krótkie czasy odpowiedzi, ale ma słabą Izolacja między kontami. CGI wyraźnie rozdziela użytkowników, ale zużywa ogromną ilość czasu procesora na każde żądanie. FastCGI zmniejsza obciążenie, ale pozostaje mniej wydajne niż dobrze dostrojone PHP-FPM. LSAPI idzie o krok dalej, gdy używane jest LiteSpeed, i stabilizuje zwłaszcza opóźnienia ogona przy wielu jednoczesnych połączeniach.

Handler Wydajność Bezpieczeństwo Wymagania dotyczące pamięci RAM Skalowalność Scenariusz operacyjny
mod_php Wysoki Niski Niski Średni Małe witryny, rzadkie szczyty
CGI Niski Wysoki Wysoki Niski Treści statyczne, testy
FastCGI Średni Średni Średni Średni rozwiązanie tymczasowe
PHP-FPM Bardzo wysoki Wysoki Niski Wysoki Hosting współdzielony, CMS
LSAPI Najwyższy Średni Bardzo niski Bardzo wysoki Wysoki ruch, e-commerce

PHP-FPM w praktyce: procesy, pule, tuning

PHP-FPM działa z pulami pracowników, które pobierają zapytania z kolejki, a tym samym Szczyty obciążenia eleganckie amortyzowanie. Tworzę osobną pulę dla każdej strony internetowej, dzięki czemu konfiguracja, limity i kontekst użytkownika pozostają oddzielone, a Bezpieczeństwo wzrasta. W praktyce opłacalne są ustawienia adaptacyjne, takie jak pm = dynamic lub ondemand, ponieważ liczba aktywnych procesów dostosowuje się do zapotrzebowania. Decydujące znaczenie ma prawidłowe wymiarowanie pm.max_children i limitów czasowych, aby kolejka nie rosła, a mimo to pozostały rezerwy pamięci RAM. Na początek zalecam sprawdzenie parametrów w sposób ustrukturyzowany; szczegóły dotyczące precyzyjnego dostrajania wyjaśniam tutaj: Zarządzanie procesami PHP-FPM.

LSAPI i LiteSpeed: najwyższa wydajność przy dużej współbieżności

LSAPI przechowuje procesy PHP w pamięci i ogranicza zmiany kontekstu, co pozwala na wyświetlanie treści dynamicznych za pomocą HTTP/3 i QUIC są dostarczane jeszcze płynniej. Przy pełnym obciążeniu opóźnienie P95/P99 pozostaje bardziej stabilne niż w przypadku wielu alternatywnych rozwiązań, co Doświadczenie użytkownika wyraźnie poprawiła się. Regularnie obserwuję więcej zapytań na sekundę i krótszy czas TTFB na stronach sklepu i treści, zwłaszcza gdy OPcache i pamięć podręczna serwera współpracują ze sobą. Korzyść ta widoczna jest nie tylko w wartościach średnich, ale także w sesjach równoczesnych, sesjach z brakami w pamięci podręcznej i „zimnych“ procesach PHP. Aby zrozumieć różnicę w architekturze, przeczytaj przegląd LiteSpeed kontra Nginx a następnie podejmuje decyzję dotyczącą stosu.

WordPress i WooCommerce: prawidłowe klasyfikowanie wartości pomiarowych

W WordPressie osiągam wysokie wyniki dzięki PHP 8.2 na FPM lub LSAPI. req/s-wartości, podczas gdy WooCommerce generuje nieco mniej żądań na sekundę dzięki sesjom, logice koszyka i większej liczbie dostępów do bazy danych. Test ma znaczenie dopiero w realistycznych warunkach. Ruch uliczny z mieszanką trafień i braków w pamięci podręcznej. Krytyczny CSS, pamięć podręczna obiektów i trwałe połączenia przesuwają granicę, od której powstają wąskie gardła. Szczególnie pomocne są krótkie TTL dla często zmienianych treści oraz zróżnicowane klucze pamięci podręcznej dla języka, statusu użytkownika i typu urządzenia. Dzięki temu strona pozostaje szybka, mimo że dostarcza spersonalizowane treści.

Bezpieczeństwo i izolacja: pule, kontekst użytkownika, limity

W przypadku hostingu wieloużytkownikowego preferuję oddzielne baseny na konto, aby prawa, ścieżki i limity pozostały wyraźnie oddzielone od siebie. mod_php dzieli wspólny kontekst, co Ryzyko zwiększa się, gdy projekt ma luki. FPM lub LSAPI z konfiguracjami dla poszczególnych użytkowników znacznie ograniczają tę powierzchnię ataku, ponieważ procesy są uruchamiane pod danym użytkownikiem. Dodatkowo istnieje możliwość ustawienia różnych opcji php.ini na poziomie projektu bez wpływu na inne witryny. Limity zasobów, takie jak max_execution_time i memory_limit dla każdej puli, zapobiegają spowolnieniu serwera przez wartości odstające.

Zużycie zasobów i planowanie pamięci RAM

Każdy moduł PHP zajmuje, w zależności od kodu, rozszerzeń i OPcache-Rozmiar pamięci znacznie się różni, dlatego mierzę rzeczywiste zużycie zamiast zgadywać. Narzędzia takie jak ps, top lub systemd-cgtop pokazują, ile pamięci RAM faktycznie zajmują aktywne procesy i kiedy. Swapping grozi. Następnie ustalam pm.max_children konserwatywnie, pozostawiając rezerwę dla bazy danych, serwera WWW i usług pamięci podręcznej i obserwuję opóźnienie P95 poniżej wartości szczytowej. Jeśli pozostają rezerwy, stopniowo zwiększam liczbę procesów potomnych i ponownie sprawdzam. W ten sposób całkowita pojemność rośnie w sposób kontrolowany, bez przeciążania serwera.

Metodologia pomiaru: od TTFB do P99

Oceniam nie tylko wartości średnie, ale przede wszystkim P95– i opóźnienia P99, ponieważ odzwierciedlają one rzeczywiste doświadczenia pod obciążeniem. Stos może działać z identyczną przepustowością, a mimo to działać gorzej przy P99, jeśli Kolejki rosnąć. Dlatego testuję zimne i ciepłe pamięci podręczne, mieszam żądania odczytu i zapisu oraz stosuję realistyczne wartości współbieżności. Bez rozgrzewki OPcache ostrożnie interpretuję wyniki, ponieważ wiele systemów po kilku wywołaniach rozgrzewki staje się znacznie szybszych. Dopiero po przeprowadzeniu reprezentatywnych testów podejmuję decyzję dotyczącą obsługi, strategii buforowania i limitów procesów.

Przewodnik dotyczący wyboru operatora

W przypadku małych stron z niewielką liczbą logowań wystarczy mod_php lub oszczędny FPM-Konfiguracja, o ile uwzględnione zostaną kwestie bezpieczeństwa. Jeśli wzrośnie współbieżność, przejdę na PHP-FPM z oddzielnymi pulami dla każdego projektu i konsekwentnie aktywuję OPcache. W przypadku bardzo dynamicznych sklepów i wielu sesji preferuję LiteSpeed z LSAPI, aby utrzymać niskie wartości P95 i P99. Ci, którzy ze względu na cenę lub architekturę pozostają przy Apache/Nginx, bardzo dobrze radzą sobie z dobrze dostrojonym FPM. We wszystkich przypadkach pomiary w realistycznych warunkach mają większe znaczenie niż testy porównawcze na pustym systemie.

Konfiguracja praktyczna: buforowanie, sesje, limity czasowe

Stawiam na OPcache z hojną Pamięć-Alokacja, aby rzadko dochodziło do wypierania kodu bajtowego, i przenoszenie sesji w miarę możliwości do Redis, aby uniknąć blokowania plików. Dzięki temu skraca się czas oczekiwania przy jednoczesnych logowaniach i spersonalizowanych stronach. W przypadku usług zewnętrznych definiuję jasne limity czasu i wyłączniki awaryjne, aby awarie nie blokowały całego żądania. Na poziomie aplikacji utrzymuję TTL pamięci podręcznej na tyle krótkie, aby zachować aktualność, ale wystarczająco długie, aby zapewnić wysoki współczynnik trafień. Osoby, które regularnie napotykają ograniczenia dotyczące pracowników, znajdą tutaj wprowadzenie: Właściwe zrównoważenie PHP-Worker.

Analiza kosztów i korzyści oraz eksploatacja

Oceniam Koszty zmiany w zamian za wymierny zysk w zakresie opóźnień, przepustowości i niezawodności. Przejście z FastCGI na PHP-FPM często przynosi większe korzyści niż zmiana numeru podwersji PHP, ponieważ Proces-Zarządzanie i buforowanie działają w sposób ciągły. LSAPI jest szczególnie opłacalne, jeśli LiteSpeed jest już w użyciu i obsługuje wielu jednoczesnych użytkowników. Osoby zmieniające stos powinny uważnie śledzić logi i metryki oraz przygotować ścieżki rollbacku. Najbardziej wiarygodne wyniki zapewnia planowana operacja A/B trwająca kilka dni.

Współpraca serwerów internetowych: Apache-MPM, Nginx i Keep-Alive

W praktyce decydujące znaczenie ma nie tylko moduł obsługi PHP, ale również tryb serwera WWW. mod_php współpracuje z Apache w trybie prefork-MPM, ale blokuje wykorzystanie nowoczesnych modeli zdarzeń. Jeśli chcesz efektywnie obsługiwać HTTP/2, dłuższe fazy Keep-Alive i tysiące połączeń, postaw na Apache. wydarzenie + PHP-FPM lub Nginx/LiteSpeed jako frontend. Konsekwencja: liczba potrzebnych procesów PHP nie zależy od liczby połączeń TCP, ale od faktycznej liczby w tym samym czasie bieżących żądań PHP. Multipleksowanie HTTP/2/3 zmniejsza więc obciążenie serwera WWW związane z nagłówkami, ale nie zmienia nic w przypadku zbyt małych pul PHP.

Nginx zazwyczaj przekazuje żądania do FPM za pośrednictwem FastCGI. Zwracam uwagę na krótkie read_timeout- oraz send_timeoutWartości na serwerze proxy, w przeciwnym razie pojawią się błędy 502/504 przy zawieszonych upstreamach, mimo że PHP nadal działa. W środowiskach Apache ograniczam Keep-Alive tak, aby długie połączenia bezczynne nie zajmowały puli wątków. LiteSpeed abstrahuje wiele z tych kwestii, ale w pełni wykorzystuje swoją przewagę dopiero dzięki LSAPI.

OPcache, JIT i preloading: co naprawdę pomaga

OPcache jest obowiązkowy. W praktyce wymiaruję opcache.memory_consumption duża (np. 192–512 MB w zależności od bazy kodu) i zwiększam opcache.max_accelerated_files, aby nie dochodziło do eksmisji. W przypadku kompilacji, które rzadko są wdrażane, wyłączam validate_timestamps lub ustaw wyższą wartość revalidate_freq, aby zaoszczędzić na wywołaniach systemowych. Ładowanie wstępne może przyspieszyć działanie frameworków, ale wykazuje swoje działanie przede wszystkim przy spójnej strukturze autoload. JIT PHP rzadko przynosi korzyści w przypadku klasycznych obciążeń sieciowych, a nawet może zużywać pamięć RAM; włączam go tylko wtedy, gdy potwierdzają to testy porównawcze przeprowadzone w rzeczywistych warunkach.

Zarządzanie kolejką i przeciwciśnieniem

Większość wąskich gardeł nie powstaje w procesorze, ale w kolejka. Jeśli liczba żądań przekracza możliwości przetwarzania przez pracowników, kolejka rośnie, a opóźnienie P95/P99 gwałtownie wzrasta. Upewniam się, że pm.max_children jest wystarczająco duża, aby pochłonąć typowe szczyty, ale wystarczająco mała, aby zachować rezerwę pamięci RAM. pm.max_requests Ustawiam umiarkowaną wartość (np. 500–2000), aby wycieki pamięci nie powodowały długotrwałego działania. listen.backlog musi być dostosowany do backlogu serwera WWW, w przeciwnym razie jądro przerwie połączenia pod obciążeniem. Mierząc częstotliwość przybywania (żądania na sekundę) i średni czas obsługi, można za pomocą prostych obliczeń wydajności ocenić, od jakiej współbieżności następuje spadek opóźnienia.

Limity czasu, przesyłanie plików i długie procesy

Długie przesyłanie plików lub wywołania API blokują pracowników. Wyznaczam jasne granice: max_execution_time oraz request_terminate_timeout w FPM zapobiegają niekończącemu się przetwarzaniu wadliwych żądań. Na poziomie proxy synchronizuję proxy_read_timeout/fastcgi_read_timeout z limitami FPM, aby nie doszło do przedwczesnego 504. Duże pliki przesyłam strumieniowo, ograniczam post_max_size oraz upload_max_filesize surowo i planuję dedykowane punkty końcowe, aby nie wpływać negatywnie na pozostały ruch. W przypadku długotrwałych zadań typu cron przenoszę pracę do Wskazówki lub zadania CLI, zamiast blokować pracowników front-endu na kilka minut.

Sesje i blokowanie w szczegółach

Sesje PHP są domyślnie blokujący. Drugie żądanie tego samego użytkownika czeka, aż pierwsze zwolni sesję – co jest fatalne dla WooCommerce, jeśli równolegle działają wywołania Ajax. Wcześnie kończę zapisy sesji za pomocą session_write_close(), gdy nie są już potrzebne żadne mutacje. Dzięki Redis jako backendowi sesji zmniejsza się opóźnienie I/O, ale zasady blokowania pozostają ważne. Za load balancerami świadomie wybieram między sesjami sticky (proste, mniej skalowalne) a wzorcami bezstanowymi z pamięcią podręczną obiektów, aby skalowanie horyzontalne działało prawidłowo.

Monitorowanie i rozwiązywanie problemów

Bez telemetrii tuning jest jak lot na ślepo. Aktywuję status FPM i slowlogi dla każdej puli, aby zobaczyć wąskie gardła i zidentyfikować zapytania, które rzucają się w oczy.

; dla każdego puli pm.status_path = /status ping.path = /ping ping.response = pong request_slowlog_timeout = 3s slowlog = /var/log/php-fpm/www-slow.log pm.max_requests = 1000

Jeśli pojawia się błąd 502/504, najpierw sprawdzam: czy kolejka FPM jest pełna? Czy występuje kradzież CPU lub swap? Czy limit czasu serwera WWW jest zgodny z limitami FPM? Sprawdź smaps na pracownika pokazuje rzeczywiste wykorzystanie RSS, podczas gdy netstat/ss Wykrywa przepełnienia backlogu. W przypadku OPcache obserwuję współczynnik trafień i liczbę ponownych walidacji, aby uniknąć ewakuacji.

Kontenery, gniazda i limity zasobów

W kontenerach najczęściej używam TCP zamiast gniazd Unix między serwerem WWW a FPM, aby uniknąć ograniczeń przestrzeni nazw i ułatwić równoważenie obciążenia. Ważna jest spójność cgroup-Limity: Jeśli kontener ma tylko 1–2 GB pamięci RAM, pm.max_children musi być odpowiednio mniejsze, w przeciwnym razie zadziała OOM-killer. Limity procesora mają duży wpływ na czas reakcji; planuję rezerwę i weryfikuję opóźnienie P95 poniżej limitu. Kwestie NUMA i Core Affinity stają się istotne przy bardzo dużym obciążeniu, podczas gdy LSAPI w konfiguracjach LiteSpeed optymalizuje wiele z nich wewnętrznie.

Wiele wersji PHP i rozszerzeń

Wielu hostów obsługuje równolegle kilka wersji PHP. Izoluję pule dla każdej wersji i utrzymuję Rozszerzenia smukły. Każdy dodatkowy moduł zwiększa pamięć RAM na pracownika i może wydłużyć czas uruchamiania. Konsekwentnie usuwam nieużywane rozszerzenia; często przynosi to większe korzyści niż niewielki wzrost pm.max_children. Podczas aktualizacji planuję krótkie fazy rozgrzewki dla OPcache, aby po wdrożeniu nie wszyscy użytkownicy doświadczyli jednocześnie zimnego startu.

Dieta RAM i realistyczne planowanie wydajności

Zamiast wartości ryczałtowych, ustalam średnie i maksymalne zapotrzebowanie na pamięć RAM na pracownika przy użyciu ruchu na żywo. Na tej podstawie wyprowadzam: (dostępna pamięć RAM – system/baza danych/pamięć podręczna) / pamięć RAM na pracownika = maksymalny rozsądna wartość pm.max_children. Dodatkowo zachowuję rezerwę 15–25 % na wypadek wzrostu obciążenia, pamięci podręcznej jądra i nieprzewidzianych skoków. Jeśli aplikacja sporadycznie zwiększa zużycie pamięci, obniżam limit lub zmniejszam pm.max_requests, aby częściej recyklingować procesy.

Strategia testowania: powtarzalne obciążenie i rzeczywiste wzorce

Korzystam z profili testowych, które łączą zimne i ciepłe pamięci podręczne, łączą GET/POST i stopniowo zwiększają współbieżność. Ważne: dopiero po aktywowaniu OPcache i realistycznych czasach myślenia widzę, czy system pozostaje stabilny pod względem zachowań użytkowników. Ramp-up trwający kilka minut zapobiega sztucznym szczytom podczas uruchamiania. Ocena koncentruje się na TTFB i P95/P99, a nie tylko na średnim RTT lub czystym req/s.

Przykłady błędów z praktyki

  • Wiele 504 poniżej wartości szczytowej: kolejka FPM pełna, zbyt mały backlog, limity czasu na serwerze proxy krótsze niż w FPM.
  • Zacinanie się podczas wdrażania: wypieranie OPcache, brak rozgrzewki, zbyt mała wartość opcache.memory_consumption.
  • Dobre wartości średnie, słabe P99: zbyt wiele długich operacji (I/O, zewnętrzne API), brak przerywania obwodu.
  • Wysokie obciążenie procesora, niskie req/s: blokady sesji lub niebuforowane zapytania do bazy danych, które ograniczają seryjność.

Bezpieczeństwo eksploatacji i przywracanie stanu poprzedniego

Każda zmiana w handlerze lub parametrach puli jest wykonywana za pomocą Flagi funkcji lub stopniowo. Obserwuję logi błędów i logi spowolnień, P95 i wskaźnik błędów oraz definiuję jasny plan przywrócenia stanu poprzedniego w przypadku spadku wskaźników. Druga pula z identyczną wersją, ale innymi parametrami umożliwia szybką zmianę A/B bez przestojów. Przy pełnym obciążeniu sprawdza się krótka, automatyczna redukcja współbieżności (backpressure) zamiast niekontrolowanego uruchamiania nowych pracowników.

Krótkie podsumowanie

W przypadku dynamicznych stron internetowych, z których korzysta jednocześnie wielu użytkowników, preferuję LSAPI na LiteSpeed, podczas gdy PHP-FPM na Apache lub Nginx zapewnia najlepszą Wszechstronny mod_php pozostaje specjalnym przypadkiem dla bardzo prostych projektów bez ścisłej izolacji. Decydujące znaczenie mają realistyczne testy z ciepłym OPcache, sensownymi limitami puli i czystym buforowaniem. Kto niezawodnie zmniejsza opóźnienia, mierzy P95/P99 i reaguje najpierw na problemy związane z ogonem, a nie na wartości średnie. W ten sposób aplikacja osiąga zauważalnie szybsze odpowiedzi i większe rezerwy na szczytowy ruch.

Artykuły bieżące