Ciągle trzeba przeładowywać PHP-FPM


27

Mamy dość mocno obciążony serwer z nginx i PHP-FPM. Mamy 6 stron internetowych na tym serwerze, na których działają PHP-FPM i nginx. Oprogramowanie to wszystko vBulletin 3.8 i WordPress. Bazy danych znajdują się na osobnym serwerze.

Ponieważ są to bardzo popularne strony internetowe, zwykle odwiedzamy online 7-8 000 użytkowników, przy czym każda strona w większości trafia do bazy danych. Wierzę, że to jest przyczyną naszych problemów.

Ponieważ mamy tak wiele dużych baz danych na serwerze MySQL, a ponieważ zapytania mogą być, szczerze mówiąc, znacznie lepsze w oprogramowaniu, myślę, że MySQL czasami nie zwróci wyników do PHP w odpowiednim czasie, tworząc efekt kaskady, który ostatecznie powoduje, że wszystko się zatrzymuje, dopóki nie przeładujemy PHP-FPM. Po wykonaniu tej czynności wszystko znów działa poprawnie.

Mam problem z rozwiązywaniem tego problemu, ponieważ tak naprawdę nie mogę rozpoznać niczego z dzienników. W dzienniku powolnych zapytań MySQL nie widzę nic interesującego, gdy pojawia się przestój. W logach nginx widzę tysiące wpisów mówiących, że upłynął limit czasu żądania odczytu lub limit czasu połączenia (To PHP-FPM). W dziennikach PHP-FPM widzę wiele wierszy z napisem „upłynął limit czasu wykonania (31 sekund), kończący się

W tym momencie po prostu zupełnie nie wiem, gdzie szukać problemu. Oczywiście wszystko, co się dzieje, dzieje się, ponieważ skrypty te czasami nie działają wystarczająco szybko (zwykle ładują się w ciągu sekundy, ale dzieje się coś, co powoduje, że czas ładowania gwałtownie wzrasta). Zdarza się to wiele razy dziennie i stało się dla nas sporym problemem.

Na razie mam po prostu crontab do obsługi przeładowywania php5-fpm co 10 minut, co rozwiązuje problem awarii. Oczywiście, gdy PHP się ładuje, nginx zgłasza błąd bramy 502, więc nie jest to zbyt duże rozwiązanie.

PHP ma pamięć podręczną APC, jeśli to ma znaczenie. Przeczytałem w kilku miejscach, że APC może powodować zawieszanie się w pewnych okolicznościach.

Wszelkie wskazówki byłyby pomocne. Naprawdę chciałbym nie martwić się o tę maszynę przez cały czas.

Oczywiście można podać więcej informacji. Po prostu daj mi znać, czego potrzebujesz.

Aktualizacja: Właśnie skopiowałem apc.php do katalogu głównego i uzyskałem dostęp do niego, aby zobaczyć nasze statystyki. Sprawy wyglądały dobrze. Następnie kliknąłem link, aby przejść do statystyk użytkownika i BOOM serwer natychmiast się zawiesił. Ponownie załadowałem php-fpm, a następnie ponownie załadowałem stronę statystyk użytkownika i wszystko poszło dobrze. Poczekano minutę, ponownie załadowano, serwer ponownie się zawiesił.

Zdecydowanie wydaje się to być związane z APC. Pytanie brzmi - jak to naprawić?

Konfiguracja APC:

[apc]
apc.enabled="1"
apc.stat = "1"
apc.max_file_size = "2M"
apc.localcache = "1"
apc.localcache.size = "256"
apc.shm_segments = "1"
apc.ttl = "3600"
apc.user_ttl = "7200"
apc.gc_ttl = "3600"
apc.cache_by_default = "1"
apc.filters = ""
apc.write_lock = "1"
apc.num_files_hint= "10000"
apc.user_entries_hint="10000"
apc.shm_size = "1G"
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.include_once_override = "0"
apc.file_update_protection="2"
apc.canonicalize = "1"
apc.report_autofilter="0"
apc.stat_ctime="0"

Aktualizacja 2: Poczyniliśmy tutaj pewne postępy. Okazuje się, że przyczyną awarii była wtyczka buforująca WordPress (W3 Total Cache). Nadal nie wiemy, dlaczego, ale z wyłączoną obsługą PHP działamy już od prawie 4 godzin bez przeładowań, spowolnień i awarii. Nadal używamy APC na forach vBulletin i nie ma żadnych problemów. Czy jest jakiś sposób, aby ustalić, DLACZEGO APC ulega awarii? Chciałbym używać go w naszych instalacjach WordPress, ale nie kosztem delikatnego systemu.


Czy możesz opublikować jakiekolwiek ustawienia związane z APC?
Kyle

Tak, dobry pomysł. Gotowy.
Kevin

Ile masz pamięci RAM i wymiany na tym komputerze? Ile zużywa się, gdy zaczyna umierać?
Kyle

2
APC jest strasznie buggy koszmar, i był jedynym źródłem katastrof takich jak ta na jednym z moich stron internetowych na lata . W końcu całkowicie się go pozbyłem; a PHP jest teraz solidny. Jeśli chcesz buforować, wypróbuj Zend Opcache, który jest również domyślną pamięcią podręczną z PHP 5.5.
Michael Hampton

1
Tak, skończyło się na APC, który powodował awarię PHP. Kiedy wyłączyliśmy APC, przestaliśmy ciągle restartować PHP.
Kevin,

Odpowiedzi:


27

Używasz php-fpm, więc sugeruję być bardziej agresywny w stosunku do tego, jak długo dzieci php-fpm mogą żyć. Musisz znaleźć słaby punkt między krótko żyjącymi wątkami / dziećmi a stabilnością. Domyślne ustawienia php-fpm są zbyt hojne dla każdego systemu produkcyjnego, IMHO.

Zmniejszyłbym liczbę pm.max_requests dla twoich pul produkcyjnych. Myślę, że domyślnie jest to 200. Zacznę od 50 i zobaczę, dokąd cię to zaprowadzi.

W przypadku niepowodzenia / uzupełnienia tego można również wypróbować te globalne opcje (AFAIK, wszystkie są domyślnie wyłączone):

emergency_restart_threshold=3
emergency_restart_interval=1m
process_control_timeout=5s

Co to znaczy? Jeśli 3 procesy potomne PHP-FPM zakończą działanie za pomocą SIGSEGV lub SIGBUS (tj. Awaria) w ciągu 1 minuty, PHP-FPM ma się ponownie uruchomić automatycznie. Procesy potomne czekają 5 sekund na reakcję na sygnały z mastera.

To powinno sprawić, że twoja pula wątków roboczych PHP będzie ładna, świeża i czysta. Im dłużej pracownik będzie mógł składać wnioski, tym bardziej będzie niestabilny. Istnieje również wyższe ryzyko wycieków pamięci.

Oto ładny przegląd wszystkich opcji konfiguracji, o których tu wspomniałem, a także innych: http://myjeeva.com/php-fpm-configuration-101.html

Mam nadzieję, że te wskazówki pomogą! Pamiętaj, aby dostosować i obserwować, niestety nie wydaje się, że istnieje ogólna zasada, istnieje zbyt wiele zmiennych, które wpływają na zachowanie i stabilność PHP.


1
Jakie jest twoje zdanie na temat używania crona do restartowania php5-fpm co godzinę?
CMCDragonkai

2
Jest to dość niechlujny sposób na zrobienie tego i może w ogóle nie działać. PHP-FPM ma wiele wbudowanych poprawek, więc lepiej użyć tej poprawki.
Rouben,

1
Ta odpowiedź wskazała mi właściwy kierunek. Widziałem podobny problem jak ten sam, rozwiązaniem dla mnie było zmienić pmz dynamiccelu ondemandi wszystko wydaje się być obecnie pracuje wielki ze wszystkimi innymi wartościami domyślnymi.
llanato

(w php-fpm.conf) powinno być „=” zamiast „” oddzielając klucz i wartość. emergency_restart_threshold = 3 emergency_restart_interval = 1m time_control_timeout = 5s
justyy

DostajęERROR: [/etc/php/7.0/fpm/pool.d/www.conf:135] unknown entry 'emergency_restart_threshold'
deweydb
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.