„Zbyt wiele plików jest otwartych” w systemie Mac OSX po uruchomieniu apache w PHP z XDebug przez pewien czas

13

Korzystam z systemu Mac OS X 10.9.4, w tym wbudowanego serwera Apache2 z PHP 5.5.14 z brew (pakiety: php55, php55-intl, php55-pdo-pgsql, php55-xdebug).

Po uruchomieniu tej konfiguracji działa całkiem dobrze. Jednak po pewnym czasie będę uruchamiać na błędach 403 dla każdego żądania. Przejrzałem dziennik błędów apache i znalazłem coś takiego:

[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP Warning:  require_once(/Users/daniel/Development/massiveart/sulu-complete/app/bootstrap.php.cache): failed to open stream: Too many open files in /Users/daniel/Development/massiveart/sulu-complete/web/website.php on line 10, referer: http://sulu.lo/de
[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP Stack trace:, referer: http://sulu.lo/de
[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP   1. {main}() /Users/daniel/Development/massiveart/sulu-complete/web/website.php:0, referer: http://sulu.lo/de
[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP Fatal error:  require_once(): Failed opening required '/Users/daniel/Development/massiveart/sulu-complete/web/../app/bootstrap.php.cache' (include_path='.:/usr/local/Cellar/php55/5.5.14/lib/php') in /Users/daniel/Development/massiveart/sulu-complete/web/website.php on line 10, referer: http://sulu.lo/de
[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP Stack trace:, referer: http://sulu.lo/de
[Fri Jul 25 05:28:18 2014] [error] [client 127.0.0.1] PHP   1. {main}() /Users/daniel/Development/massiveart/sulu-complete/web/website.php:0, referer: http://sulu.lo/de
[Fri Jul 25 05:28:40 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de
[Fri Jul 25 05:28:41 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de
[Fri Jul 25 05:28:41 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de
[Fri Jul 25 05:28:41 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de
[Fri Jul 25 05:28:45 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de
[Fri Jul 25 05:28:45 2014] [crit] [client 127.0.0.1] (24)Too many open files: /Users/daniel/Development/massiveart/sulu-complete/web/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable, referer: http://sulu.lo/de

Wygląda mi na to, że pliku nie można już odczytać i jakoś zwraca 403. Dowiedziałem się już o niektórych limitach, ale zwraca returnctl Mam nieograniczony twardy limit na otwarte pliki:

 ~ $ launchctl limit
    cpu         unlimited      unlimited
    filesize    unlimited      unlimited
    data        unlimited      unlimited
    stack       8388608        67104768
    core        0              unlimited
    rss         unlimited      unlimited
    memlock     unlimited      unlimited
    maxproc     709            1064
    maxfiles    256            unlimited

Próbowałem już także ustawić maxfiles na 4096 za pomocą polecenia launchctl limit maxfiles 4096 16384, ale problem nadal powraca po pewnym czasie. Masz pomysł, co jeszcze mogę sprawdzić?

AKTUALIZACJA : Po uruchomieniu lsof -c httpdpolecenia, zgodnie z sugestią Gordona Davissona, widzę, że istnieje mnóstwo wpisów takich jak:

httpd   1361 _www   15u    IPv4 0xb306b48659f63853       0t0     TCP localhost:50603->localhost:cslistener (CLOSED)

Mogę powiedzieć, że aplikacja, której używam, korzysta z websockets, a także korzysta z rezerwy, gdy websockets nie są dostępne lub ich odpowiednik nie działa na serwerze. Co mnie (CLOSED)dezorientuje to -part, dlaczego wciąż jest na liście?

AKTUALIZACJA : Po pewnym czasie przejrzałem port cslistener, który w rzeczywistości ma 9000, czyli znowu ten port, który xdebug oczekuje na zdalne debugowanie. Wydaje mi się, że mam tam złą konfigurację lub błąd w xdebug (używam XDebug 2.2.5, zainstalowanego przez brew)

Daniel Rotter
źródło

Odpowiedzi:

14

Czy korzystasz z PHPStorm z XDEBUG na Macu?

Mam ten sam problem. Znalazłem otwarty błąd zgłoszony do XDEBUG tutaj:

http://bugs.xdebug.org/view.php?id=1070

Aktualizacja

Ten błąd został teraz naprawiony:

Właśnie połączyłem łatkę Seana Dubois, która powinna naprawić ten \ o /! Aktualizacja będzie w 2.3.4 i 2.4.0.

Wierzę, że to jest zatwierdzenie: https://github.com/xdebug/xdebug/commit/6efc6588efc277d648a78b69c11c721992c996f9

Upewnij się, że używasz zaktualizowanej wersji z tą poprawką.

Steve Tauber
źródło
Nie do końca rozwiązanie, ale myślę, że to odpowiada na pytanie
Daniel Rotter
Zasadniczo Xdebug przecieka deskryptory plików dla detektorów połączeń (przepraszam, jeśli jest to technicznie niepoprawne, taki jest pomysł), gdy klient debugujący nie jest otwarty. Aby rozwiązać problem, upewnij się, że klient debugera jest otwarty, gdy zdalny debuger rozpocznie sesję debugowania. Oczywiście lepszym rozwiązaniem byłoby naprawienie błędu przez programistów.
mcdado,
Dzieje się tak również z niektórymi otwartymi debuggerami (na przykład PhpStorm). Mam nadzieję, że to naprawią :)
Steve Tauber,
Jest to dość poważne, mam nadzieję, że wkrótce zostanie wydana poprawka.
Hubert Perron,
1
Innym rozwiązaniem jest zestaw xdebug.remote_enable=0w php.inina przełomie połączeń zdalnych Xdebug gdy ich nie używasz. Wymagane ponowne uruchomienie Apache.
Gregory Cosmo Haun
7

Jestem prawie pewien, że masz coś uruchomionego w Apache (prawdopodobnie moduł PHP, ale trudno jest być pewnym), że nieszczelne deskryptory plików. Oznacza to, że otwiera pliki, a następnie pozostawia je otwarte na czas nieokreślony. W takim przypadku zwiększenie limitu otwartych plików powoduje, że osiągnięcie limitu zajmuje więcej czasu. To, co naprawdę musisz zrobić, to wyśledzić, co otwiera wszystkie pliki i pozostawia je otwarte.

Prawdopodobnie możesz dowiedzieć się, co się dzieje z poleceniem lsof(„LiSt Open Files”):

sudo lsof -c httpd

Uruchom go, gdy apache nie działa długo, aby zobaczyć, co jest normalne, a następnie ponownie, gdy osiągnie limit. W drugim pliku wyjściowym znajduje się wiele dodatkowych plików, których nie ma na pierwszej liście. Zauważ, że będzie to nieco skomplikowane przez fakt, że wyświetli listę plików otwartych przez wszystkie procesy httpd, a (w zależności od ustawień apache i obciążenia serwera) może być ich duża liczba; ważną rzeczą jest liczba plików otwieranych przez pojedynczy proces, a nie suma wszystkich procesów serwera. Możesz także użyć sudo lsof -p someprocessIDdo wyświetlenia listy pojedynczego procesu serwera na raz.

Mam nadzieję, że zobaczenie, jakie są dodatkowe otwarte pliki, da ci dobry pomysł, co je otwiera i pozostawia otwarte.

Gordon Davisson
źródło
Próbowałem, zaktualizowałem pytanie.
Daniel Rotter
Dokładnie nie znam dokładnego znaczenia stanów gniazd TCP, ale wydaje mi się, że połączenia z odpowiednikiem nie zamykają się prawidłowo. Czy to działa na porcie cslistener (numer 9000)? Jak dokładnie twoja aplikacja zamyka połączenia z odpowiednikiem? Czy to możliwe, że zamyka sesję TCP, ale nie deskryptor pliku?
Gordon Davisson
1
Dowiedziałem się, że 9000 jest portem, na którym nasłuchuje xdebug, więc czy to możliwe, że błąd jest w tym rozszerzeniu?
Daniel Rotter
3

Dodanie następującej linii do xdebug.ini również rozwiązało problem

xdebug.remote_autostart = 0
Femi Veys
źródło
1

Tak samo jest z OSX 10.9.4 oraz Apache 2.2 i PHP 5.3 z Brew.

Chociaż tak naprawdę nie rozwiązuje to problemu, możesz go rozwiązać, ustawiając ustawienie Apache MaxRequestsPerChild na około 10 - co powinno być odpowiednie do programowania.

diff -r 2c0473b696fd -r acf809f04b17 apache2/2.2/httpd.conf
--- a/apache2/2.2/httpd.conf    Thu Aug 14 16:14:25 2014 -0500
+++ b/apache2/2.2/httpd.conf    Thu Aug 14 16:19:10 2014 -0500
@@ -437,7 +437,7 @@
 # necessary.

 # Server-pool management (MPM specific)
-#Include /usr/local/etc/apache2/2.2/extra/httpd-mpm.conf
+Include /usr/local/etc/apache2/2.2/extra/httpd-mpm.conf

 # Multi-language error messages
 #Include /usr/local/etc/apache2/2.2/extra/httpd-multilang-errordoc.conf
diff -r 2c0473b696fd -r acf809f04b17 apache2/2.2/extra/httpd-mpm.conf
--- a/apache2/2.2/extra/httpd-mpm.conf  Thu Aug 14 16:14:25 2014 -0500
+++ b/apache2/2.2/extra/httpd-mpm.conf  Thu Aug 14 16:19:10 2014 -0500
@@ -38,7 +38,7 @@
     MinSpareServers       5
     MaxSpareServers      10
     MaxClients          150
-    MaxRequestsPerChild   0
+    MaxRequestsPerChild  10
 </IfModule>

 # worker MPM

Powinno to zaoszczędzić przynajmniej od konieczności ponownego uruchamiania apache co jakiś czas, aby pozbyć się tych wyciekających plików

barryp
źródło