...

WordPress PHP-FPM Dzieci: Nieprawidłowe wartości blokują strony

Dzieci PHP-FPM decydują w WordPress o tym, czy żądania przebiegają płynnie, czy też utkną w kolejce. Pokażę ci, jak nieprawidłowe pm.max_children-wartości blokują strony, pochłaniają pamięć RAM i sposób obliczania czystych wartości.

Punkty centralne

Zanim przejdę dalej, krótko podsumuję kluczowe przesłania:

  • pm.max_children określa, ile jednoczesnych żądań PHP jest uruchomionych.
  • Zbyt mało Dzieci generują kolejki, 502/504 i wysokie TTFB.
  • Za dużo prowadzi do wąskich gardeł pamięci RAM, swapów i zabójstw OOM.
  • Formuładostępna pamięć RAM PHP / rozmiar procesu × 0,7-0,8.
  • Iteracyjny Strojenie z monitorowaniem zapewnia najlepszą długoterminową wydajność.

Dlaczego nieprawidłowe strony PHP-FPM Children są blokowane

Każde dynamiczne żądanie WordPress wymaga własnego Pracownik, i to właśnie te procesy są kontrolowane przez pulę poprzez pm.max_children. Jeśli ustawię zbyt niską wartość, żądania będą gromadzić się w kolejce i TTFB zauważalnie wzrasta. Jeśli ustawię zbyt wysoką wartość, każdy proces potomny zużywa dodatkową pamięć RAM, a serwer przełącza się na swap. Wszystko zwalnia w swapie, dopóki Apache lub Nginx nie zgłoszą 502/504 lub zabójca OOM nie zakończy procesów. Zdrowa przepustowość jest osiągana tylko wtedy, gdy liczba dzieci odpowiada rzeczywistemu budżetowi pamięci RAM i obciążeniu projektu.

Formuła dla pm.max_children w praktyce

Zaczynam od prostego wzoru: dostępna pamięć RAM dla PHP podzielona przez średni rozmiar procesu potomnego, pomnożona przez jeden Współczynnik bezpieczeństwa Określam pamięć RAM na proces za pomocą ps i kolumny RSS; dla typowych stosów WordPress, 50-250 MB jest często poprawne. Na serwerze 4 GB rezerwuję pamięć dla Linuksa, bazy danych i usług pamięci podręcznej, pozostawiając około 1,5-2 GB na PHP pozostaje. Na przykład, jeśli średnia procesu wynosi 100 MB, 2000 / 100 × 0,75 = 15 dzieci. Liczba ta służy jako punkt wyjścia, który udoskonalam zgodnie z profilem obciążenia, buforowaniem i mieszanką wtyczek.

Wartości początkowe dla typowych konfiguracji WordPress

Dla małych blogów z 2 GB RAM, 8 dziećmi, pm = dynamic i pm.max_requests ok. 800. Dla średnich projektów z 4 GB RAM ustawiam 12 dzieci, start_servers 4, min_spare_servers 4. Duże sklepy z 8 GB RAM lub więcej korzystają z 21-40 dzieci; jeśli obciążenie jest stale wysokie, pm = static może zapewnić stałą przepustowość. Następnie sprawdzam stosunek wykorzystania procesora, użycia pamięci RAM i czasów odpowiedzi, aby dokonać dokładnych korekt. Jeśli chcesz zagłębić się bardziej, możesz znaleźć podstawowe informacje na stronie optymalne ustawienia PHP-FPM.

Pomiar procesów: jak określić wymagania dotyczące pamięci RAM

Najpierw określam rzeczywisty rozmiar procesów, zanim ustawię wartości, ponieważ kryształowe kule nie pomagają tutaj i kosztują pieniądze. Wydajność. Polecenie ps -ylC php-fpm -sort:rss zwraca rozmiary RSS, które monitoruję przez kilka minut. Procesy często rosną podczas aktualizacji lub zadań cron, dlatego w obliczeniach uwzględniam skoki. Używam również htop i free -h, aby sprawdzić rezerwy pamięci RAM i ilość wymiany. Używam tych danych do określenia wiarygodnej średniej i wybieram konserwatywny współczynnik bezpieczeństwa.

Ważne parametry w skrócie

Oprócz pm.max_children, inne opcje puli określają, jak czysto WordPress przetwarza żądania i jak dobrze zwalnia pamięć, co zauważalnie zmniejsza Stabilność pm reguluje tryb: dynamiczny dostosowuje liczbę procesów do obciążenia, statyczny utrzymuje stałą liczbę. pm.max_requests zapobiega rozrostowi pamięci poprzez ponowne uruchamianie procesów po X żądaniach. request_terminate_timeout chroni przed zawieszaniem się spowodowanym przez wadliwe lub powolne skrypty. Z tym zestawem, pokrywam 90 procent rzeczywistych praktycznych przypadków.

Parametry Funkcja Rekomendacja WordPress
pm Tryb sterowania procesem dynamiczny dla zmiennego obciążenia; statyczny dla stale wysokiego ruchu
pm.max_children Maksymalna liczba jednoczesnych pracowników Dostępna pamięć RAM PHP / rozmiar procesu × 0,75
pm.max_requests Recykling procesów 300-1,000; raczej niższe z WooCommerce
request_terminate_timeout Anulowanie długotrwałych żądań 60-120 sekund przeciwko wieszakom

Dynamiczny, na żądanie czy statyczny - który tryb jest odpowiedni dla Ciebie?

Wybieram tryb pasujący do profilu obciążenia: dynamiczny jest moim domyślnym, ponieważ elastycznie dostosowuje liczbę aktywnych procesów, a tym samym oszczędza pamięć RAM, gdy niewiele się dzieje. statyczny Używam go, gdy obciążenie jest stałe i potrzebuję twardych zobowiązań w zakresie opóźnień i przepustowości - na przykład podczas kampanii lub sprzedaży. na żądanie jest odpowiednia dla serwerów z długimi fazami bezczynności: Procesy są tworzone tylko wtedy, gdy jest to wymagane i kończone ponownie po braku aktywności. Kompromisem są zimne starty; pierwsze żądanie dla nowego procesu jest wolniejsze. Dla ondemand ustawiłem pm.process_idle_timeout czysto (np. 10-20s), z dynamicznym utrzymuję start_servers, min_spare_servers oraz max_spare_servers ciasno, aby basen szybko się skalował, ale nie „nadmuchiwał“.

Przykład konfiguracji dla puli

Na Debianie/Ubuntu plik puli znajduje się zwykle w /etc/php/8.x/fpm/pool.d/www.conf, co daje mi jasny obraz Struktura dla dostosowań. Ustawiam pm na dynamiczny, zakotwiczam realistyczną wartość dla pm.max_children i utrzymuję zapasowy serwer. Recykling ustawiam na 500, aby wcześnie ograniczyć wycieki i wzrost pamięci RAM. Po każdej zmianie testuję obciążenie i usuwam wąskie gardła przed dalszym zwiększaniem wartości. Podstawowe informacje na temat wartości granicznych można znaleźć na stronie Optymalizacja pm.max_children.

pm = dynamic
pm.max_children = 15
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500
request_terminate_timeout = 90s

Wiele basenów, gniazd i czysta izolacja

W przypadku wielu projektów lub wyraźnie oddzielonych ról (frontend vs. admin/REST), ustawiam oddzielne baseny z własnym użytkownikiem i gniazdem. W ten sposób każda pula ogranicza swoje własne dzieci, a jedna wartość odstająca nie blokuje reszty. Na hoście preferuję Gniazda Unix w porównaniu do TCP (listen = /run/php/site.sock) - mniejsze opóźnienia, mniejszy narzut. Używam TCP między Nginx/Apache i PHP-FPM na różnych hostach/kontenerach. Używam listen.owner, listen.group oraz listen.mode spójne i, jeśli to konieczne, podnieść listen.backlog aby krótkie skoki obciążenia nie powodowały błędów połączenia. Dzięki dedykowanej puli administratorów mogę osiągnąć ściślejszy request_terminate_timeout napęd i pm.max_requests niższe bez spowalniania puli frontendowej z silnym buforowaniem.

Rozpoznawanie objawów i prawidłowa reakcja

Jeśli w dzienniku błędów regularnie pojawia się komunikat „server reached pm.max_children“, oznacza to, że pula jest ograniczona do Równoległość i zwiększam go umiarkowanie. Jeśli 502/504 występuje jednocześnie z wysokim wykorzystaniem swapu, resetuję pm.max_children i obniżam pm.max_requests. Jeśli procesor wzrasta przy niskim wykorzystaniu pamięci RAM, zapytania lub logika PHP są zwykle blokowane; optymalizuję bazę danych i buforowanie. Jeśli żądania utkną, pomaga bardziej rygorystyczny request_terminate_timeout i analiza dziennika ze znacznikami czasu. Sprawdzam wyraźne szczyty w odniesieniu do cronjobs, indeksów wyszukiwania i działań administratora.

Stan FPM i slowlog: precyzyjna diagnoza

Aktywuję Status na pulę (pm.status_path) i odczytać kluczowe dane, takie jak aktywne procesy, maksymalna liczba osiągniętych dzieci, kolejka odsłuchu oraz maksymalna kolejka nasłuchiwania wyłączony. Stale rosnąca kolejka listy wyraźnie pokazuje: zbyt mało dzieci lub blokowanie backendów. Ustawiłem również request_slowlog_timeout (np. 3-5s) oraz slowlog-path. W ten sposób widzę ślady stosu żądań, które się opóźniają - często są to zewnętrzne wywołania HTTP, złożone zapytania WooCommerce lub manipulacje obrazami. Z catch_workers_output Ostrzeżenia od pracowników są gromadzone w dziennikach. Na podstawie tych danych decyduję, czy większa równoległość pomaga, czy też muszę rozwiązać wąskie gardła w kodzie / DB.

Monitorowanie: 3-5 dni czystej oceny

Po dostrojeniu obserwuję szczyty obciążenia przez kilka dni, ponieważ krótkoterminowe wahania oszustwo. Rejestruję RAM, swap, 502/504, TTFB i liczbę aktywnych procesów w statusie FPM. Poniżej 80 procent wykorzystania pamięci RAM bez wymiany i bez kolejek, mam rację. Jeśli wąskie gardła pojawiają się podczas działań takich jak kasa, wyszukiwanie lub import, specjalnie dostosowuję pm.max_children i pm.max_requests. Każdy krok jest wykonywany w małych korektach i z nowym pomiarem.

Szczegółowe obliczenia pamięci: RSS, PSS i pamięć współdzielona

Zmienna procesowa jest trudna: RSS (Resident Set Size) zawiera również segmenty współdzielone, takie jak OPcache i biblioteki. Dlatego szybko przeceniam zużycie pamięci RAM, jeśli po prostu obliczę „RSS × dzieci“. Lepszym rozwiązaniem jest PSS-view (Proportional Set Size), który sprawiedliwie rozdziela pamięć współdzieloną pomiędzy procesy - pomocne są tu narzędzia takie jak smem. Obliczenia obejmują OPcache (np. 256 MB + ciągi znaków), APCu (np. 64-128 MB) i proces główny. PHP pamięć_limit nie jest średnią, ale górnym limitem na żądanie; mogą wystąpić pojedyncze szczyty, ale liczy się średnia wartość. Planuję bufor, aby skoki, wdrożenia i cronjobs nie powodowały natychmiastowej zamiany, i zostawiam pm.max_requests aby ograniczyć rozrost pamięci.

Zmniejszenie obciążenia specyficznego dla WordPress

Najpierw zmniejszam obciążenie PHP, zanim zwiększę liczbę dzieci, ponieważ szybszy współczynnik trafień pamięci podręcznej oszczędza czas rzeczywisty. RAM. Pełnostronicowe pamięci podręczne drastycznie zmniejszają liczbę żądań PHP, co zwiększa pojemność dla kasy, wyszukiwania i administratora. OPcache z memory_consumption 256 MB przyspiesza kod bajtowy i odciąża pulę. W praktyce utrzymuję limit pamięci PHP na poziomie 256 MB, aby poszczególne wtyczki nie spowalniały serwera. Więcej informacji na temat wąskich gardeł można znaleźć w przewodniku PHP-Worker jako wąskie gardło.

Baza danych i pamięć podręczna w równowadze

Każdy pracownik PHP potencjalnie generuje Połączenie z bazą danych. Jeśli zwiększę pm.max_children, jednoczesne obciążenie DB również wzrośnie. Dlatego sprawdzam MySQL/MariaDB: max_connections, bufor (innodb_buffer_pool_size) i planer zapytań. Redis/Memcached musi działać równolegle - maxclients, limit pamięci i opóźnienia. Instancja WordPress z 20 aktywnymi dziećmi może łatwo nasycić DB, jeśli kilka drogich zapytań działa równolegle. Dlatego dostrajam DB (indeksy, powolne zapytania) i ustawiam na Trwałe pamięci podręczne obiektów, zanim zwolnię kolejne dzieci. Zwiększa to przepustowość bez przeciążania backendu.

WooCommerce, Cron i Admin: Przypadki specjalne

Sklepy generują więcej jednoczesnych dynamicznych żądań, dlatego używam czegoś Powietrze z pm.max_children. Jednocześnie mam tendencję do obniżania pm.max_requests w celu ciągłego zmniejszania rozrostu pamięci. W przypadku importów i cronjobs planuję dodatkowy budżet lub wykonuję zadania poza godzinami szczytu. Obszar administracyjny często osiąga szczyty w krótkim czasie; buforowanie zapewnia tutaj mniejszą ochronę, więc liczy się wydajna kontrola puli. Jeśli pojawiają się oznaki kolejek, zwiększam je małymi krokami i natychmiast monitoruję metryki.

Kontenery, limity vCPU i pułapki OOM

W kontenerach i maszynach wirtualnych nacisk kładziony jest na skuteczny Limit RAM (cgroups), a nie na hoście. Dlatego obliczam pm.max_children z przydzielonego limitu, a nie z „free -h“. Kontenerowe OOMy są bezlitosne - jądro mocno przerywa procesy. Liczą się również limity CPU: Więcej dzieci nie pomoże, jeśli 1-2 vCPU ograniczają czas obliczeń. Zasadą jest skalowanie obciążeń WordPressa o dużym obciążeniu IO do około 2-4× liczby vCPU; powyżej tej wartości przełączniki kontekstowe rosną, ale nie rzeczywista przepustowość. W orkiestrowanych środowiskach ostrożnie wprowadzam zmiany, obserwuję restarty podów i utrzymuję sondy gotowości/żywotności, aby krótkie fazy rozgrzewania FPM nie były liczone jako awarie.

Źródła błędów, które są często pomijane

Wiele problemów nie wynika z basenu, ale z Wtyczki, które mnożą żądania lub generują długie procesy. Indeksowane wyszukiwania, złamane reguły crawlera i nadmierne interwały heartbeat zwiększają obciążenie. Dlatego zawsze najpierw sprawdzam dzienniki, monitor zapytań i nagłówki buforowania. Jeśli obciążenie występuje tylko w przypadku niektórych adresów URL, interpretuję to jako wskazanie wąskich gardeł wtyczek lub szablonów. Dopiero gdy te problemy zostaną rozwiązane, skaluję dzieci dalej.

Zrozumienie sesji, administratora AJAX i blokad

WordPress/wtyczki działają częściowo z Sesje. Blokady sesji oparte na plikach mogą serializować żądania - pojedyncze powolne żądanie blokuje resztę tego samego identyfikatora sesji. Utrzymuję niskie wykorzystanie sesji i sprawdzam, czy administrator AJAX bursts (wp-admin/admin-ajax.php) odpala niepotrzebnie często. Heartbeat powinien być rozsądnie dławiony, w przeciwnym razie generuje obciążenie bez wartości dodanej. Jeśli występują blokady lub długie dostępy do plików, większa równoległość nie pomoże; buforowanie, szybsze I / O pamięci masowej lub inny program obsługi sesji pomogą tutaj. W logach rozpoznaję takie wzorce po wielu podobnych żądaniach rozpoczynających się w tym samym czasie z niezwykle długimi czasami wykonywania.

Limity czasu Nginx, Apache i FastCGI w skrócie

Serwer sieciowy ustawia również limity, które muszę zharmonizować z wartościami FPM, w przeciwnym razie wygasną. Strojenie. W przypadku Nginx zwracam uwagę na fastcgi_read_timeout i wystarczającą liczbę procesów roboczych. W Apache sprawdzam mpm_event, ustawienia keepalive i limity czasu proxy. Jeśli te limity nie są prawidłowe, użytkownicy zgłaszają przekroczenie limitu czasu, mimo że FPM nadal ma przepustowość. Znormalizowane budżety czasowe utrzymują spójną ścieżkę od klienta do PHP.

Strategia wdrażania, testy i obsługa

Wprowadzam zmiany w pm.max_children krok po kroku i testuję je pod rzeczywistym obciążeniem. Przeładowanie FPM (graceful) przejmuje konfiguracje bez zrywania połączenia. Przed większymi skokami symuluję szczyty (np. rozpoczęcie sprzedaży) i obserwuję, co następuje kolejka odsłuchu, CPU, RAM, 95-99 percentyl opóźnienia i stopy błędów. Dokumentuję przyjęte założenia, aby późniejsi członkowie zespołu zrozumieli, dlaczego wartość została wybrana w ten sposób. Ustawiam alarmy dla: swap > 0, „max children reached“ w statusie, wzrost 502/504 i opóźnienie DB. Gwarantuje to, że platforma pozostanie stabilna nawet miesiące później, gdy zmieni się ruch i mix wtyczek.

Krótkie podsumowanie

Nieprawidłowe ustawienie PHP-FPM-dzieci spowalniają WordPressa, albo w kolejkach, albo w limicie pamięci RAM. Określam rozmiar procesu, rezerwuję pamięć dla usług systemowych i ustawiam pm.max_children z buforem. Następnie sprawdzam pm.max_requests, request_terminate_timeout i tryb pm = dynamiczny lub statyczny zgodnie z profilem obciążenia. Buforowanie, OPcache i czyste wtyczki zauważalnie zmniejszają liczbę żądań PHP. Jeśli wdrożysz te kroki konsekwentnie, utrzymasz responsywność stron i niezawodność serwera.

Artykuły bieżące