Envato Elements - pobierasz co chcesz, ile chcesz

Niedawno pisałem, że przeniosłem stronę WebInsider.pl z DigitalOcean (ale nadal polecam) na VPS w HitMe.

Oczywiście przy takiej przeprowadzce wsparłem się m.in. transferem plików/danych między serwerami z wykorzystaniem SSH, i wprawdzie w teorii można w ten sposób spróbować przenieść cały system z jednej maszyny na drugą, to raczej dotyczy to sytuacji, gdy obie maszyny są jak najbardziej zbliżone pod względem konfiguracji (np. z Raspberry Pi na drugą Raspberry Pi), dlatego zazwyczaj w ten sposób kopiuje tylko niektóre katalogi (np. strony internetowe, katalogi domowe), a resztę (np. zabezpieczenia, webserwer) instaluje i konfiguruje od podstaw – przy dobrej organizacji (i procedurach) nie zajmuje to aż tak dużo czasu, a przy okazji jest okazja przypomnieć sobie co nie co.

Czasem w takich momentach pojawia mi się też pomysł na nowy wpis/poradnik – i tak było i tym razem, bo o ile o PHP-FPM i PHP Pools pisałem nawet niedawno, to jeszcze nie poruszałem tematu związanego z trybem pracy menedżera procesów PHP, a jest to dość ciekawe zagadnienie, które w wielu poradnikach sprowadza się zazwyczaj do domyślnego trybu pracy, który nie zawsze jest najlepszy…

Menedżer procesów PHP-FPM (process manager)

Wprawdzie w większości przypadków domyślne ustawienie będzie się pewnie sprawdzało całkiem nieźle, to jednak warto wiedzieć jak można zarządzać procesami PHP na serwerze, choćby w przypadku gdy na naszej stronie zwiększy się znacznie ruch, czy zacznie brakować pamięci lub czasu/mocy procesora.

Przykładowym błędem związanym z tym tematem jaki możecie spotkać w logach usługi PHP (/var/log/php5-fpm.log) będzie np.:

[DATA GODZINA] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

Jest to dość częsty błąd na stronach z trochę większym ruchem niż „kilak(set) osób dziennie”, i nie wdając się w zbytnie szczegóły oznacza tyle, że trzeba zwiększyć ilość procesów PHP (PHP-FPM) jakie mogą w danej chwili pracować (w przypadku cytowanego błędu zostawiłem wartość domyślną, czyli 5).

Maksymalna ilość procesów

Oczywiście w tym przypadku najprościej zwiększyć maksymalną procesów PHP jaka może działać w tym samym czasie, poprzez modyfikację tylko jednego parametru – pm.max_children:

sudo nano /etc/php5/fpm/pool.d/www.conf

I zmieniamy:

pm.max_children = 5

np. na 10:

pm.max_children = 10

Na koniec wystarczy zrestartować usługę PHP:

sudo service php5-fpm restart

Po co ustawiać w ciemno, jak można policzyć

Oczywiście możecie mieć wątpliwości, jaką wartość ustawić by było dobrze – nie ma na to jednoznacznej odpowiedzi, ja zazwyczaj stopniowo zwiększam liczbę (ilość ;-)) procesów, aż błąd zniknie, a do tego dodaje mały zapas.

Oczywiście nie jest to tak, ze wartość/liczbę możemy zwiększać baz ograniczeń, bo każdy proces to nie tylko dodatkowe obciążenie procesora, ale – a może przede wszystkim – wykorzystanie kolejnym megabajtów pamięci RAM, której zazwyczaj nigdy nie jest za dużo… ;-)

Na obecnym serwerze (XEN2G) mam 2 GB pamięci RAM (+ 4 GB pamięci SWAP, ale tego typu pamięci sugeruję nie brać pod uwagę w wyliczeniach, no chyba, że nie macie wyjścia), a więc jest to 2048 MB.

Średnio jeden proces (jedno wystąpienie) PHP u mnie to jakieś 3-3,3% pamięci, czyli ok 61-62 MB. Na wszelki wypadek dajmy z zapasem, więc powiedzmy, że będzie to 70 MB (ale nie kierujcie się tutaj moim przypadkiem, sprawdzicie jak to wygląda u Was).

Tak więc 2048 MB dzielimy na 70, co nam daje ~29, ale trzeba pamiętać, że z pamięci RAM korzystają również inne usługi, w tym choćby system.

Dlatego lepiej sprawdzić ilość wolnej pamięci RAM podczas normalnej pracy serwera, i podzielić ją przez 70-75. Otrzymaną wartość warto jeszcze trochę odchudzić, i mniej więcej o to co zostanie możemy zwiększyć liczbę procesów PHP (pm.max_children).

Zarządzanie procesami (instancjami) PHP-FPM

Gdy już wiemy jaką wartość maksymalnie możemy ustawić (przynajmniej teoretycznie) to warto poznać jeszcze tryby pracy menedżera procesów PHP, gdyż nie w każdym przypadku domyślny tryb będzie najlepszy.

Static

Celowo nie zaczynam od domyślnie aktywnego trybu (dynamic), a od trybu static, gdyż na nim będzie mi chyba najłatwiej wyjaśnić o co chodzi, a zarazem będzie to dobry punkt wyjścia dla pozostałych – już bardziej skomplikowanych w swojej zasadzie działania – trybów.

W tym trybie – jak sama nazwa wskazuje – ustalamy na sztywno liczbę procesów która będzie cały czas działać w systemie, nawet jak nie będzie w danej chwili takiej potrzeby.

Ustawiamy właściwie tylko jeden parametr – ilość aktywnych procesów:

sudo nano /etc/php5/fpm/pool.d/www.conf

pm = static
pm.max_children = 5

Pewnie niektórym ten tryb już się spodobał, bo ilość dodatkowych ustawień jest równa zeru, ale ten tryb ma też swoje wady – niezależnie od ruchu na stronie, niezależnie od potrzeba zawsze w systemie będzie działać określona liczba procesów, tym samym stale zajmując dla siebie pamięć RAM (70-75 MB na każdą instancję).

Na plus – oprócz prostej konfiguracji – można zaliczyć również to, że w przypadku mocno obciążonych serwerów/stron z dużym ruchem może to być najbardziej wydajny tryb, gdyż zadeklarowana liczba procesów/instancji cały czas czeka w pogotowiu do działania…

Ondemand

Drugim trybem pracy który chciałbym przedstawić jest ondemand – moim zdaniem dość niedoceniany tryb (rzadko pojawia się w poradnikach), a zwłaszcza w przypadku gdy korzystamy z niezależnych gniazd dla poszczególnych stron, na których dodatkowo ruch jest relatywnie niewielki może to być prawdziwe wybawienie dla serwera, dzięki czemu możemy oszczędzić sporo pamięci RAM (a ew. różnica w wydajności względem trybu static powinna sprowadzać się właściwie tylko do czasu potrzebnego na wystartowanie potrzebnego procesu, czyli jakieś milisekundy).

Można powiedzieć, że jest to w pewnym sensie przeciwieństwo trybu static, bo w trybie ondemand ustawiamy maksymalną liczbę procesów, ale będą one uruchamiane tylko w razie potrzeby, a po ustawionym czasie bezczynności zabijane, zwalniając tym samym zasoby.

Parametrów do ustawienia nie ma dużo więcej – dochodzi czas bezczynności:

sudo nano /etc/php5/fpm/pool.d/www.conf

pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s

W powyższej przykładowej konfiguracji mamy maksymalnie 5 procesów, które będą zabijane po 10 sekundach bezczynności.

Dynamic

No i tym sposobem dotarliśmy do trzeciego i ostatniego trybu – dynamic, czyli dynamicznego zarządzania procesami.

Jest to tryb który pewnie spotkacie w konfiguracji większości serwerów, co wynika nie tylko z tego, że jest on domyślnie aktywny, ale również z tego, że jest to chyba najbardziej uniwersalny tryb – z jednej strony procesy są tworzone i zabijane wedle potrzeb (ondemand), ale z drugiej strony możemy ustawić minimalną liczbę procesów oczekujących w stanie bezczynności na działanie (static).

Przykładowa konfiguracja usługi PHP wygląda np. tak:

sudo nano /etc/php5/fpm/pool.d/www.conf

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Jak widać jest tu sporo więcej parametrów do ustalenia niż w pierwszych 2 trybach, ale chyba nadal nie jest to nic szczególnie skomplikowanego, zwłaszcza, ze jak wspomniałem – ten tryb jest aktywny domyślnie, a więc wstępne ustawienia macie gotowe.

Mamy tu dynamiczne zarządzanie procesami (pm = dynamic), których maksymalnie będzie 5, z tego 2 starują od razu, wraz ze startem webserwera/usługi PHP. W stanie oczekiwania (bez zadań) może być minimum 1 proces, ale nie więcej niż 3.

Wyciek pamięci

Skoro już jesteśmy przy tych ustawieniach, to jest jeszcze jedne parametr – właściwie uniwersalny, bo ma zastosowanie dla każdego z opisanych powyżej trybów, a może przeciwdziałać tzw. wyciekowi pamięci jaki może się przydarzyć np. jakimś zewnętrznym modułom, a będzie się objawiał brakiem zwalniania wykorzystanej wcześniej pamięci, co w efekcie może doprowadzić nawet do wyczerpania pamięci RAM w naszym serwerze.

W tym celu wystarczy ustawić automatyczne resetowanie procesu PHP po zadeklarowanej liczbie aktywności, np. 500:

sudo nano /etc/php5/fpm/pool.d/www.conf

pm.max_requests = 500

I choć jak napiąłem, jest to uniwersalne ustawienie, to wydaje mi się szczególnie przydatne w przypadku korzystania z trybu static, gdzie poza restartem serwera lub usługi PHP procesy działają nieprzerwanie.

(!) Zgłoś błąd na stronie
Potrzebujesz profesjonalnej pomocy? Skontaktuj się z nami!
Spodobał Ci się artykuł? Zapisz się do naszego Newslettera - ZERO SPAMu, same konkrety, oraz dostęp do dodatkowych materiałów przeznaczonych dla subskrybentów!
Na podany adres e-mail otrzymasz od nas wiadomość e-mail, w której znajdziesz link do potwierdzenia subskrypcji naszego Newslettera. Dzięki temu mamy pewność, że nikt nie dodał Twojego adresu przez przypadek. Jeśli wiadomość nie przyjdzie w ciągu najbliższej godziny (zazwyczaj jest to maksymalnie kilka minut) sprawdź folder SPAM.
Młody Szymon pomógł tacie zapisać się do Newslettera WebInsider.pl i... teraz idzie popływać
WebInsider poleca księgowość wFirma
WebInsider korzysta z VPSa w HitMe.pl
WebInsider poleca VPSy DigitalOcean
WebInsider poleca serwis Vindicat
Napisz komentarz
wipl_napisz-komentarz_01Jeśli informacje zawarte na tej stronie okazały się pomocne, możesz nam podziękować zostawiając poniżej swój komentarz.

W tej formie możesz również zadać dodatkowe pytania dotyczące wpisu, na które – w miarę możliwości – spróbujemy Ci odpowiedzieć.
Linki partnerskie
Niektóre z linków na tej stronie to tzw. „linki partnerskie”, co oznacza, że jeśli klikniesz na link i dokonasz wymaganej akcji (np. zakup/rejestracja) możemy otrzymać za to prowizję. Pamiętaj, że polecamy tylko te produkty i usługi, z których sami korzystamy, i uważamy, że są tego na prawdę warte… :-)
Znaki towarowe i nazwy marek
W niektórych wpisach (oraz innych miejscach na stronie) mogą być przedstawione/użyte znaki towarowe i/lub nazwy marek, które stanowią własność intelektualną tych podmiotów, a zostały użyte wyłącznie w celach informacyjnych.
Janusz i Janusz dzięki motywowi Divi od Elegant Themes koszą siano robiąc strony