Usando xhprof, noté que file_scan_directory()
lleva más de 10 segundos ejecutar cuando se carga la primera página. ¿Por qué debería tomar tanto tiempo?
Esta es la salida de xhprofile:
7
performance
hknik
fuente
fuente
Respuestas:
Parece que te afecta un problema conocido en Drupal 7 .
Mirando esas funciones, parece que le falta un módulo o tal vez un solo archivo de un módulo. Eche un vistazo a drupal_get_filename () , llama a drupal_system_listing (), que llama a esta función si no puede encontrar el archivo solicitado. Agregue un dpm (func_get_args ()) justo antes de que llame a drupal_system_listing (), eso debería indicarle qué archivo no está encontrando.
fuente
Hay varias razones por las cuales este problema puede surgir, y para mi gran consternación, ahora me encuentro un poco informado sobre esas razones. Frustrantemente, si acaba de notar este problema después de actualizar Drupal core a 7.33+, esto podría ser un error tipográfico en cualquier módulo, incluso si no ha actualizado ese módulo.
Módulos eliminados de la base de código
Es posible que desee verificar primero el error conocido que @Berdir menciona, especialmente si recientemente ha estado eliminando módulos "no utilizados" de la base del código. Para saber si tiene módulos que están habilitados pero se han eliminado del sistema de archivos, puede ejecutar un script como el mencionado aquí , o usar el mío, escrito para una instalación de múltiples sitios en un sistema con drush, para ejecutarse del directorio base de Drupal:
o lo siguiente:
Si encuentra un módulo que se ha eliminado de la base del código, siga las instrucciones en los problemas que mencionó @Berdir.
Errores de codificación
Si no es así, es probable que su situación se deba a un error de codificación, como un archivo que se ha eliminado pero que todavía se agrega mediante una llamada a drupal_add_js (del comentario 19 en el número 1082892) o un error tipográfico desafortunado en un módulo o tema , por ejemplo
imagecache_actions
(ver https://drupal.org/node/2381357 ).En cualquier caso, para descubrir exactamente por qué sucede esto, debe saber exactamente qué archivo no puede encontrar Drupal. Así, de acuerdo con el comentario de Berdir, se puede cortar temporalmente
drupal_get_filename
enbootstrap.inc
añadiendo una llamada o un mensaje de registro justo antes de la llamada adrupal_system_listing()
. Si tiene instalado el módulo Develdpm
, funcionará; si no, puede usardrupal_set_message
o syslog. Ejemplos:Una vez que sepa lo que Drupal está buscando, es una buena apuesta que podrá averiguar a dónde ir desde allí. Mi problema fue causado por una llamada para incluir un archivo del módulo inexistente
imagcache_actions
(tenga en cuenta el error tipográfico). Entonces, busquéimagecache_actions
en mi base de código (por ejemplogrep -r imagcache_actions .
), y encontré que la versión 1.4 deimagecache_canvasactions.module
usa module_load_include fuera de cualquier llamada de función, en el alcance del archivo, con un error tipográfico. De nuevo, este error solo se expuso después de actualizar a Drupal 7.33+. Descubrí que ya se había creado un problemaimagecache_actions
, apliqué el parche y volví al negocio.fuente
Tuve un problema muy similar:
file_scan_directory()
estaba matando el sitio. Resulta que unanode_modules
carpeta enorme incrustada dentro de mi tema personalizadogulp
se estaba escaneando cada descarga de caché. Mover estos archivos fuera de la carpeta de temas (y actualizar algunas rutas en mi archivo) parecía solucionarlo. Alternativamente: creo que puedes hackearfile.inc
:'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519
fuente
El
file_scan_directory()
es una función recursiva que todos los archivos que coinciden para un directorio dado. Sus usosis_dir()
yopendir()
llamadas PHP pueden ser más costosos en términos de llamadas al sistema de E / S. La rutina de arranque simple de Drupal (ptime drush ev ""
. Ej. ) Puede llamarfile_scan_directory
unas pocas miles de veces (según la complejidad de la jerarquía de carpetas de Drupal, p. Ej., El número de módulos y sus carpetas).En mi caso, tenía ~ 1500 llamadas a
file_scan_directory
(24 segundos en total que consisten en 2 llamadas desdedrupal_system_listing
adentrocommon.inc
, luego las otras llamadas se dividieron por llamadas recursivas afile_scan_directory
sí mismo.Para mejorar el rendimiento en las llamadas de E / S, debe implementar el almacenamiento en caché de archivos. Esto se puede lograr instalando y habilitando OPCache (
opcache.enable=1
) y modificando su configuración (ver: ¿Cómo usar PHP OPCache? ). También se recomienda utilizar el almacenamiento en caché basado en memoria, como memcached / redis.Cuando utilice la interfaz de línea de comandos (como
drush
), también debe habilitarlaopcache.enable_cli=1
.Después del cambio, puede verificar las llamadas al sistema más consumidoras utilizando algunos depuradores disponibles.
P.ej
En Linux usando
strace
(pulsar Ctrl- Cpara finalizar):En Unix usando
dtrace
(usando las sondas estáticas DTrace de PHP ), por ejemploTambién puede considerar optimizar
drupal_system_listing()
ofile_scan_directory()
implementar caché estática, por ejemploO para el almacenamiento en caché de
file_scan_directory
llamadasdrupal_system_listing()
, compruebe el siguiente parche disponible en: file_scan_directory debe almacenarse en caché .fuente