portable appserv php mysql apache

appserv - xampp php 7



PHP-FPM se bloquea al tener demasiados usuarios al hacer un trabajo pesado (4)

Tengo un servidor que ejecuta Apache / 2.2.22 (Debian), PHP 5.6.17 como FPM y MySQL 5.6.25.

El proyecto se ejecuta utilizando un CMS llamado Redaxo (no creo que sea tan importante, pero te lo diré de todos modos). En Redaxo hay algunas funciones que llevan algún tiempo (por ejemplo, eliminar el caché y reconstruirlo toma 1-2 minutos). En este momento, cuando otros usuarios entran en el sitio web, FPM se bloquea con un 500 Internal Server Error y tengo que volver a cargar la página varias veces hasta que desaparezca el Error del servidor y se complete el proceso.

Noté que esto solo ocurrirá si hay demasiados usuarios en el sitio al mismo tiempo y solo cuando se realizan operaciones pesadas.

10 usuarios al mismo tiempo, simplemente navegando = No hay problema
10 usuarios al mismo tiempo que simplemente navegan, mientras que la eliminación de caché = 500 Error para todos.

Lo verifiqué rechazando el sitio web para todos excepto para mí (.htaccess deny / allow with ip). Entonces hice la operación pesada y no tuve ningún problema. Tan pronto como varias personas volvieron a estar en el sitio, el problema volvió a estar allí.

¿Qué podría ser? ¿Qué información necesitas de mí?

Estos valores están establecidos (no comentados) en el php-fpm.conf

[global] pid = /run/php5-fpm.pid error_log = /var/log/php5-fpm.log emergency_restart_threshold = 0 include=/etc/php5/fpm/pool.d/*.conf

Estos valores están establecidos (no comentados) en el proyecto específico fpm.conf

[projectname] user = projectname group = projectname listen = /var/run/php5-fpm-projectname.sock listen.owner = projectname listen.group = projectname listen.mode = 0660 pm = dynamic pm.max_children = 150 pm.start_servers = 10 pm.min_spare_servers = 10 pm.max_spare_servers = 30 chdir = / php_value[upload_max_filesize] = 128M php_value[max_post_size] = 128M php_value[max_execution_time] = 180 php_value[memory_limit] = 256M

¿El script cuando falla hace mucho con MySQL y la creación de archivos si ayuda? Pero es bastante grande, ¿no estoy seguro de si debería publicarlo aquí? ¿O si es hasta el problema?

El registro de errores de apache dice esto o bien

[Tue Feb 09 10:54:01 2016] [error] [client {IP}] (104)Connection reset by peer: FastCGI: comm with server "/fcgi-bin-php5-fpm-projectnmae" aborted: read failed [Tue Feb 09 10:54:01 2016] [error] [client {IP}] FastCGI: incomplete headers (0 bytes) received from server "/fcgi-bin-php5-fpm-projectnmae"

o esto

[Tue Feb 09 11:00:46 2016] [error] [client {IP}] FastCGI: incomplete headers (0 bytes) received from server "/fcgi-bin-php5-fpm-projectname" [Tue Feb 09 11:00:48 2016] [error] [client {IP}] (104)Connection reset by peer: FastCGI: comm with server "/fcgi-bin-php5-fpm-projectname" aborted: read failed

El fpm-log dice lo siguiente. Por supuesto siempre diferentes tiempos

[10-Feb-2016 09:40:59] WARNING: [pool projectname] child 10970 exited on signal 7 (SIGBUS) after 50.186611 seconds from start [10-Feb-2016 09:40:59] NOTICE: [pool projectname] child 11092 started

A veces hay una advertencia como esta en ella.

[09-Feb-2016 11:00:41] WARNING: [pool projectname] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 6 total children [09-Feb-2016 11:00:42] WARNING: [pool projectname] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 7 total children

Aquí hay más información de depuración

[18-Feb-2016 17:42:01] WARNING: [pool projectname] child 9088 exited on signal 7 (SIGBUS) after 70.130564 seconds from start [18-Feb-2016 17:42:01] NOTICE: [pool projectname] child 9205 started [18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 said into stderr: "NOTICE: PHP message: PHP Notice: Undefined offset: 1181 in /var/www/projectname/htdocs/redaxo/include/classes/class.ooarticle.inc.php on line 44" [18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 said into stderr: "NOTICE: PHP message: PHP Warning: Invalid argument supplied for foreach() in /var/www/projectname/htdocs/redaxo/include/classes/class.ooredaxo.inc.php on line 134" [18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 exited on signal 7 (SIGBUS) after 183.838886 seconds from start [18-Feb-2016 17:43:55] NOTICE: [pool projectname] child 9330 started [18-Feb-2016 17:44:00] WARNING: [pool projectname] child 9101 exited on signal 7 (SIGBUS) after 188.987954 seconds from start [18-Feb-2016 17:44:00] NOTICE: [pool projectname] child 9336 started


A menos que tenga un montón de RAM disponible (como más de 16 GB disponibles), le sugiero que se esté quedando sin recursos y esto está causando el error 500.

Su configuración indica que puede generar hasta 150 procesos PHP-FPM y cada uno puede usar 256 MB de memoria; esto solo permite que el servidor PHP-FPM use más de 38 GB de memoria, y si no está disponible, causará que 500 error.

Calcule lo que cada servidor puede usar de la memoria y luego configúrelo correctamente. ¿Este CMS necesita hasta 256 MB de memoria? ¿Podría ejecutarse con menos memoria (como 32 MB)? Si MySQL, Apache y Nginx están en este mismo servidor, separe la memoria que utilizará cada uno, luego establezca el valor adecuado para pm.max_children y php_value[memory_limit] .

Tenga en cuenta que la falta de recursos está en todo el sistema, por lo que si su proceso de PHP utiliza toda la memoria disponible, MySQL podría terminar colapsando por quedarse sin recursos (esta podría ser la razón del registro no encontrado).

Si puede decir cuánta memoria tiene disponible, puedo ayudarlo a configurar estos números.

También sería bueno saber cuánta memoria está disponible antes de emitir el borrado de la memoria caché y cuánta está disponible mientras se está ejecutando; de hecho, podría estar usando demasiada memoria y sofocando los otros procesos (y si usa PHP-CLI, puede no tener límite de memoria).


Cada vez que el servidor cuelga, puede ver un error diferente si php y / o Apache alcanzan sus límites.

Si su host es Unix / Linux, ¿podría verificar los resultados del comando $ top mientras el CMS está haciendo alguna de las tareas difíciles?

Si ve agotada la memoria, una gran parte de la memoria de intercambio está llena y la CPU está en la parte superior, intente ajustar el límite de memoria de php.ini para distribuir los recursos. Pero probablemente necesites aumentar los recursos, la memoria y la CPU.

Si la memoria y la CPU no están ocupadas, es posible que haya asignado menos memoria a php. Puede ejecutar más trabajadores php-fpm, aumentar el límite de memoria por proceso, ... ver http://linuxbsdos.com/2015/02/17/how-to-reduce-php-fpm-php5-fpm-ram-usage-by-about-50/ . También eche un vistazo a la memoria de Apache y la configuración de la CPU.


Esto podría ser el efecto de algún problema de bloqueo de su servidor MySQL.

Tienes que conectarte a tu host MySQL durante la latencia.

  • Si no puedes conectarte, te quedas sin la cantidad de conexiones concurrentes permitidas de tu servidor MySQL o tu usuario

  • Si puede conectarse, debe ver lo que devuelve el comando mysql "show processlist". Ahora tienes 2 opciones:

    • Muchos "Esperando bloqueo de caché de consulta": esto requerirá que cambie parte de la configuración de su servidor MySQL. ( Esto puede ser causado por un caché de consulta de gran tamaño )

    • Tiene una solicitud que toma todos los recursos, los cuales tendrá que optimizar.


He estado viendo esto por algunos días y finalmente estoy decidiendo agregar mi valor de 2 centavos.

He estado usando FPM durante mucho tiempo y es una gran cosa, pero obtener una configuración escalable es otra historia. Hay muchas cosas que pueden salir mal causando su problema, pero tengo una sospecha.

Quiero centrarme en los errores de PHP que aparecen en su salida porque indican que algo va mal que no debería ser. Me pregunto si, mientras borra la memoria caché y los usuarios navegan por el sitio, al mismo tiempo extraen datos incompletos porque se elimina cierta información o se está reconstruyendo. Incluso podría estar viendo una situación en la que el caché se está eliminando, y las cosas nuevas se almacenan en caché al mismo tiempo. No he mirado el código del CMS para la eliminación de la memoria caché, pero los errores de PHP que mostró parecen indicar que se están recuperando algunos datos no válidos en el proceso.

Una cosa a tratar sería bloquear explícitamente las tablas antes de la eliminación de la memoria caché y luego liberarlas. De esta manera, el usuario no puede leer ni escribir datos mientras se borran cosas. En cualquier secuencia de comandos a la que llame para borrar el caché, intente agregar una consulta LOCK TABLES articles WRITE, othertable WRITE, anyothertable WRITE . Esto evitará que otras sesiones (usuarios) lean o actualicen esas tablas mientras se borra la memoria caché.

Los usuarios son impacientes, si intentan cargar una página y no les da ningún comentario, a menudo intentan volver a cargar, o retroceden y hacen clic en otros enlaces. Esto puede hacer que el número de procesos FPM aumente. Si 10 usuarios se actualizan 5 veces, ahora tienes 50 procesos adicionales ejecutándose y también colgando empeorando las cosas.

-- Otras cosas

Incrementa ProxyTimeout o Timeout en Apache. Si tiene un script que puede ejecutarse por un tiempo, Apache terminará la conexión si no recupera ningún dato en un período de tiempo determinado (lo que puede estar bien). Si se tarda 5 minutos en borrar la memoria caché y PHP no envía nada hasta que finalice, y Apache tiene un tiempo de espera de 120 segundos, se desconectará la conexión antes de que se complete, lo que resultará en un tiempo de espera como el que está viendo. Tengo muchos sitios que pueden hacer cosas por hasta 10 minutos, por lo que mi tiempo de espera en Apache es de 600 segundos. Esto permite que las solicitudes de PHP terminen sin romper las cosas.

Algo más que noté es que estás usando sockets de dominio Unix para la comunicación FPM. Esto puede estar bien, pero no se escalan bien en sitios muy ocupados. Yo sugeriría usar un socket TCP en su lugar. listen = 127.0.0.1:9000 Tendrá que modificar Apache para conectarse usando tcp en lugar de un socket de dominio.

Establezca listen.backlog para que las conexiones puedan ponerse en cola cuando esté ocupado. Probablemente también deberá ajustar el valor del kernel net.core.somaxconn usando sysctl ya que generalmente es bastante bajo.

Apache MPM: cambie a MPM worker si aún no lo está utilizando. Ya que estás usando FPM, worker es un MPM muy eficiente para Apache, mucho mejor que prefork (a menudo el predeterminado). Asegúrese de ajustarlo a sus necesidades (es decir, servidores de configuración, subprocesos y MaxRequestWorkers adecuadamente).

-- Clausura

No creo que haya nada demasiado complicado, lo primero que vería es garantizar que la eliminación de la memoria caché pueda finalizar sin interrupciones. Incluso si esto significa que los usuarios ven una página de mantenimiento por un par de minutos o que sus solicitudes se bloquean por un corto tiempo hasta que se complete, si evita 500 y errores, es un precio pequeño que pagar.

Sinceramente, creo que hay un problema con la eliminación del caché y la navegación de personas que está afectando el proceso y que las cosas se demoren más de lo necesario o se rompan.

Déjeme saber si tiene alguna pregunta o no dude en ponerse en contacto conmigo.