Используя xhprof, я заметил, что file_scan_directory()
при загрузке главной страницы требуется более 10 секунд. Почему это займет так много времени?
Это вывод xhprofile:
7
performance
hknik
источник
источник
Ответы:
Похоже, вы столкнулись с известной проблемой в Drupal 7 .
Глядя на эти функции, похоже, что отсутствует модуль или, может быть, один файл модуля. Посмотрите на drupal_get_filename () , он вызывает drupal_system_listing (), который вызывает эту функцию, если не может найти запрошенный файл. Добавьте dpm (func_get_args ()) прямо перед вызовом drupal_system_listing (), который должен сообщить вам, какой файл он не находит.
источник
Есть несколько причин, по которым эта проблема может возникнуть, и, к моему великому разочарованию, я теперь немного разбираюсь в этих причинах. К сожалению, если вы только что заметили эту проблему после обновления ядра Drupal до версии 7.33+, это может быть опечаткой в любом модуле, даже если вы не обновили этот модуль.
Модули удалены из базы кода
Вы можете сначала проверить наличие известной ошибки, о которой упоминает @Berdir, особенно если вы недавно удаляли «неиспользуемые» модули из базы кода. Чтобы выяснить, есть ли у вас модули, которые включены, но были удалены из файловой системы, вы можете запустить скрипт, такой как упомянутый здесь, или использовать мой, написанный для установки на нескольких сайтах в системе с drush, для запуска из базового каталога Drupal:
или следующее:
Если вы найдете модуль, который был удален из базы кода, следуйте указаниям в проблемах, упомянутых @Berdir.
Ошибки кодирования
Если это не так, ваша ситуация, вероятно, вызвана ошибкой кодирования, такой как файл, который был удален, но все еще добавляется вызовом drupal_add_js (из комментария 19 в выпуске №1082892) или неудачной опечаткой в модуле или теме Например
imagecache_actions
(см. https://drupal.org/node/2381357 ).В любом случае, чтобы точно выяснить, почему это происходит, вам нужно точно знать, какой файл Drupal не может найти. Таким образом, в соответствии с комментарием Berdir, вы можете временно взломать
drupal_get_filename
вbootstrap.inc
путем добавления вызова журнала или сообщение непосредственно перед вызовомdrupal_system_listing()
. Если у вас установлен модуль Devel, то онdpm
будет работать; если нет, вы можете использоватьdrupal_set_message
или системный журнал. Примеры:Как только вы узнаете, что ищет Drupal, можно поспорить, что вы сможете найти, куда идти дальше. Моя проблема была вызвана вызовом для включения файла из несуществующего модуля
imagcache_actions
(обратите внимание на опечатку). Итак, я искалimagecache_actions
в своей кодовой базе (напримерgrep -r imagcache_actions .
) и обнаружил, что версия 1.4imagecache_canvasactions.module
использует module_load_include вне любого вызова функции, в области файла, с опечаткой. Опять же, эта ошибка была обнаружена только после обновления до Drupal 7.33+. Я обнаружил, что проблема уже была созданаimagecache_actions
, применила исправление и вернулась к работе.источник
У меня была очень похожая проблема -
file_scan_directory()
убивал сайт. Оказывается, огромнаяnode_modules
папка, встроенная в мою пользовательскую тему, проверялась при очисткеgulp
кеша. Перемещение этих файлов из папки темы (и обновление некоторых путей в моем gulpfile), казалось, исправило это для меня. Альтернативно: я думаю, что вы можете взломатьfile.inc
:'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519
источник
Это
file_scan_directory()
рекурсивная функция для всех файлов, соответствующих данному каталогу. Он используетis_dir()
иopendir()
вызовы PHP, которые могут быть наиболее дорогостоящими с точки зрения системных вызовов ввода / вывода. Простой загрузчик Drupal (напримерtime drush ev ""
) может вызыватьfile_scan_directory
несколько тысяч раз (в зависимости от сложности вашей иерархии папок Drupal, например, количества модулей и их папок).В моем случае у меня было ~ 1500 вызовов
file_scan_directory
(всего 24 секунды, состоящие из 2 вызовов отdrupal_system_listing
входаcommon.inc
, затем остальные вызовы были разделены на рекурсивные вызовы кfile_scan_directory
себе).Чтобы повысить производительность при вызовах ввода / вывода, вам необходимо реализовать кэширование файлов. Это может быть достигнуто путем установки и включения OPCache (
opcache.enable=1
) и настройки его параметров (см .: Как использовать PHP OPCache? ). Также рекомендуется использовать кэширование на основе памяти, такое как memcached / redis.При использовании интерфейса командной строки (например,
drush
), вы также должны включитьopcache.enable_cli=1
.После внесения изменений вы можете проверять более сложные системные вызовы, используя некоторые доступные отладчики.
Например
В Linux с помощью
strace
(нажмите Ctrl- Cчтобы закончить):В Unix с использованием
dtrace
(используя статические пробники PHP DTrace ), напримерВы можете дополнительно рассмотреть возможность оптимизации
drupal_system_listing()
илиfile_scan_directory()
внедрения статического кэша, напримерИли для кэширования
file_scan_directory
вызовов изdrupal_system_listing()
, затем проверьте следующий патч, доступный по адресу: file_scan_directory должен быть кэширован .источник