Cómo depurar Prestashop que va lento en el backoffice


#1

1. Introducción

Un problema recurrente y que afecta a Prestashop de manera muy específica es que el backOffice de la tienda funcione lento.

Los síntomas son claros: la web en general perfectamente y sistemas confirma que los servidores donde está ejecutando el Prestashop están tranquilos y sin carga: ¿qué está pasando?:thinking:

2. Sospechosos habituales

Aunque pueden existir varios factores, los sospechosos habituales son:

  1. Problemas con algún módulo ejecutando código poco optimizado que sólo se activa en el backoffice

  2. Problemas con algún módulo, el propio tema o el propio core de prestashop por el cual lanza conexiones a servidores externos que conjunturalmente van lentos. Debido a que PHP es de ejecución lineal, este queda bloqueado hasta que el servidor remoto termine de responder, causando una lentitud generaliza.

Sobre estos problemas existen registros y quejas generalizadas que suelen ocurrir cada cierto tiempo:

Aunque la descripción del problema es la misma, el problema puede estar causando por distintos módulos, el tema usado o el propio core de Prestashop.

3. Herramientas para revisar donde se está produciendo el bloqueo

De manera general, estamos buscando una llamada a función bloqueada. Pueden ser muchas pero habitualmente son llamadas a conectar a un sistema remoto (un web, un API o un servidor de base datos).

A continuación explicamos algunas de las herramientas que tienes para depurar tu Prestashop

3.1 Activar la depuración integrada de Prestashop

Dependiendo de la versión de Prestashop, se realiza pinchando en el panel de administración, parámetros avanzados, rendimiento y a continuación activamos el modo depuración:

  1. En concreto, para activar la depuración en PrestaShop 1.7 sería consultando la sección dentro de panel de administración, parámetros avanzados, y luego rendimiento:

  2. Para versiones antiguas, deberás activarlo vía FTP o ssh en el fichero config/defines.inc.php actualizando la declaración:

    define(‘PS_MODE_DEV’, true);
    define(‘PS_DEBUG_PROFILING’, true);

  3. Para versiones aún más antiguas, sería actualizar el fichero config/defines.inc.php ajustando la declaración:

    @ini_set(‘display_errors’, ‘on’);

  4. Ahora, con estas opciones activadas, harás que tu prestashop genere al final de cada página visitada un reporte haciendo profiling de cada una de las sentencias SQL, pero sobre todo de las secciones de HOOKS que tiene prestashop. Un ejemplo sería:

    Como se puede observar en el ejemplo, tenemos varias secciones que están por debajo de los 50ms. Sin embargo, hay una: initContent, que está tardando algo más.

    En este caso el retraso no es mucho. Pero si se retrasase 12.000 (ms, 12 segundos), ya sería una buena pista para buscar en Google: "prestashop very slow in initContent"

3.2 Usando crad-php-show-connections.pyc para mostrar conexiones salientes

Core-Admin.com proporciona una herramienta que permite listar las conexiones salientes y entrantes que está realizando un motor PHP-FPM.

Con él, si el retraso es causado por una conexión externa que está retrasándose, aparecerá en el listado.

El modo de uso es el siguiente.

  1. Conectar por ssh como root a la máquina. La ejecución de esta herramienta está restringida al usuario administrador de la máquina.

  2. Realizar una visita a la web o sección donde se esté produciendo el retraso.

  3. A continuación, ejecutar:

    >> crad-php-fpm-show-connections.pyc
    Process: [504] :: php-fpm: master process (/etc/core-admin/php/7.2/php-fpm.conf)
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [17776] :: php-fpm: pool asplhosting-web-example.com
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [9103] :: php-fpm: master process (/etc/core-admin/php/5.6/php-fpm.conf)
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [29780] :: php-fpm: master process (/etc/core-admin/php/7.1/php-fpm.conf)
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [11669] :: php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [17689] :: php-fpm: pool aspl-example-test.com
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [17763] :: php-fpm: pool aspl-example-test2.com
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    |
    Process: [17797] :: php-fpm: pool asplhosting-test2.com
    | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

Como podemos ver en este ejemplo, ninguno de los alojamientos ejecutando en la máquina tiene conexiones abiertas hacia afuera. El anterior sería un ejemplo de estado sano: sin conexiones pendientes dado que para tener una web ágil las conexiones se resuelven en pocos milisegundos.

En caso de haber alguna conexión sospechosa saldrá algo como:

Process: [17797] :: php-fpm: pool asplhosting-test2.com
      | COMMAND    PID          USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
php5-fpm 8814 asplhostingtest2com    9u  IPv4           78068014      0t0      TCP  **node01-customer12345.asplhosting.com:36896->lhr35s03-in-f19.1e100.net:https (ESTABLISHED)**

3.3 Usando strace sobre los procesos php/php-fpm

Otra posibilidad es utilizar la herramienta de trazado de llamadas al sistema strace.

Es una herramienta avanzada que proporciona mucha información y un nivel de detalle elevado sobre las llamadas al sistema que está haciendo cualquier proceso. La desventaja que tiene es que genera mucha información y algo cruda de manera que es necesario interpretarla.

Para ejecutarla sería:

  1. Conectar como root a la máquina vía ssh. La herramienta strace está restringida a ser ejecutada por el usuario root.

  2. A continuación ejecutar el siguiente comando particularizándolo al usuario de la web:

    >> strace -p `ps faux | grep php | grep usuario-de-la web| grep -v grep | cut -b10-16`

3.4 Qué hacer en caso de encontrase conexiones enganchadas

Si tras hacer la depuración se estima que son conexiones enganchadas, por el destino al que se dirige, por el tiempo que está en ejecución (una conexión no debería estar más de 400ms ejecutando), entonces se puede introducir una ruta nula para hacer que la conexión, en caso de produce, falle con un Destination Unreachable, haciendo que termine inmediatamente, eliminando el bloqueo.

  1. El modo de añadir una ruta nula sería:

    >> route add -host reject

  2. A continuación probar si el desbloqueo desaparece.

3.5 Desactivar módulos de prestashop

Si las anteriores indicaciones no proporcionan pistas, lo siguiente que hay que revisar es deshabilitar módulos de prestashop uno a uno hasta ver si alguno de ellos, al ser quitado, resuelve el problema.

Tras esto, se pueden reactivar todos los módulos salvo el módulo en conflicto para que puedas comenzar a trabajar en un módulo concreto, acotando enórmemente el problema.

A este respecto, existe la posibilidad de desactivar todos los módulos de terceros en un único paso que te permitirá realizar una comprobación rápida si este puede ser el problema.

Para ello, entrar en la administración -> Parámetros Avanzados -> Rendimiento, marcar “Deshabilitar módulos prestashop”:

3.6 Revisado de logs

También os recomendamos realizar un análisis de los logs asociados a la web. Para ello, revisa el siguiente artículo: