«Слишком много файлов открыто» в Mac OSX после запуска apache в PHP с XDebug в течение некоторого времени

13

Я использую Mac OS X 10.9.4, включая встроенный веб-сервер apache2 с PHP 5.5.14 от brew (пакеты: php55, php55-intl, php55-pdo-pgsql, php55-xdebug).

При запуске этой настройки она работает довольно хорошо. Однако через некоторое время я буду запускать 403 ошибки для каждого запроса. Я посмотрел журнал ошибок Apache и нашел что-то вроде следующего:

[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

Мне кажется, что файл больше не может быть прочитан, и он возвращает 403 как-то. Я уже узнал об определенных пределах, но launchctl возвращает, у меня есть неограниченное жесткое ограничение на открытые файлы:

 ~ $ 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

Я также уже пытался установить maxfiles на 4096 с помощью команды launchctl limit maxfiles 4096 16384, но проблема все еще возвращается через некоторое время. Есть идеи, что еще я могу проверить?

ОБНОВЛЕНИЕ : при выполнении lsof -c httpdкоманды, как предложено Гордоном Дэвиссоном, я вижу, что есть множество записей, подобных следующему:

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

Я могу сказать, что приложение, которое я использую, использует веб-сокеты, а также использует запасной вариант, когда веб-сокеты недоступны или аналог не запущен на сервере. Что меня смущает, так это (CLOSED)-part, почему он все еще указан?

ОБНОВЛЕНИЕ : Через некоторое время я посмотрел порт cslistener, который на самом деле является 9000, который снова является тем, какой порт xdebug прослушивает для удаленной отладки. Так что я думаю, что у меня там какая-то неправильная конфигурация, или это ошибка в xdebug (я использую XDebug 2.2.5, установленный brew)

Даниэль Роттер
источник

Ответы:

14

Вы используете PHPStorm с XDEBUG на Mac?

У меня точно такая же проблема. Я нашел открытую ошибку, поданную с XDEBUG здесь:

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

Обновить

Эта ошибка теперь исправлена:

Я только что слил патч Шона Дюбуа, который должен исправить это \ o /! Патч будет в 2.3.4 и 2.4.0.

Я считаю, что это коммит: https://github.com/xdebug/xdebug/commit/6efc6588efc277d648a78b69c11c721992c996f9

Убедитесь, что вы используете обновленную версию с этим патчем.

Стив Таубер
источник
Не совсем решение, но я думаю, что это отвечает на вопрос
Даниэль Роттер
По сути, Xdebug пропускает файловые дескрипторы для прослушивателей соединений (извините, если это технически неверно, такова идея), когда клиент отладки не открыт. Чтобы решить эту проблему, убедитесь, что клиент отладчика открыт, когда удаленный отладчик начинает сеанс отладки. Конечно, лучшим решением было бы исправление ошибки разработчиками.
McDado
Это также происходит с некоторыми открытыми отладчиками (например, PhpStorm). Надеюсь, они это исправят :)
Стив Таубер
Это довольно важно, я надеюсь, что исправление будет выпущено в ближайшее время.
Хьюберт Перрон
1
Другим решением является набор xdebug.remote_enable=0в , php.iniчтобы включить удаленные соединения Xdebug , когда они не используются. Требуется перезагрузка Apache.
Грегори Космо Хаун
7

Я почти уверен, что у вас есть что-то, работающее в apache (возможно, модуль PHP, но в этом трудно убедиться), которое пропускает дескрипторы файлов. То есть он открывает файлы, а затем просто оставляет их открытыми на неопределенный срок. Если это так, то увеличение лимита открытых файлов просто увеличивает время, необходимое для достижения лимита. Что вам действительно нужно сделать, так это отследить, что открывает все файлы и оставляет их открытыми.

Вы, вероятно, можете получить некоторое представление о том, что происходит с командой lsof("LiSt Open Files"):

sudo lsof -c httpd

Запустите его, когда Apache долго не работал, чтобы увидеть, что нормально, и снова, когда он достигнет предела. Ищите во втором выводе множество дополнительных файлов, которых нет в первом списке. Обратите внимание, что это будет несколько усложнено тем фактом, что в нем будут перечислены файлы, открытые всеми процессами httpd, и (в зависимости от настроек apache и нагрузки на сервер) их может быть много; важнее всего количество файлов, открытых одним процессом, а не общее количество всех процессов сервера. Вы также можете использовать sudo lsof -p someprocessIDдля перечисления только один процесс сервера за один раз.

Надеюсь, что вы увидите, какие дополнительные открытые файлы дадут вам хорошее представление о том, как их открывать и оставлять открытыми.

Гордон Дэвиссон
источник
Попробовал, обновил вопрос.
Даниэль Роттер
Я не очень хорошо знаю точное значение состояний сокета TCP, но мне кажется, что соединения с контрагентом не закрываются должным образом. Это работает на порту cslistener (номер 9000)? Как именно ваше приложение закрывает соединения со своим коллегой? Возможно ли, что он закрывает сеанс TCP, но не дескриптор файла?
Гордон Дэвиссон
1
Я узнал, что 9000 - это порт, который прослушивает xdebug, так возможно ли, что ошибка в этом расширении?
Даниэль Роттер
3

Добавление следующей строки в xdebug.ini также решило проблему для меня

xdebug.remote_autostart = 0
Феми Вейс
источник
1

Я получаю то же самое с OSX 10.9.4 и Apache 2.2 и PHP 5.3 от Brew.

Хотя это на самом деле не решает проблему, вы можете ее устранить, установив для параметра Apache MaxRequestsPerChild значение, подобное 10 - что должно быть хорошо для разработки.

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

Это должно избавить вас, по крайней мере, от необходимости перезапускать Apache так часто, чтобы избавиться от этих утечек файлов

barryp
источник