advertencias de php session_write_close

advertencias de php session_write_close

Todos nuestros errores se registran en NewRelic y siempre vimos algunas advertencias session_write_closeen el registro de errores. Sin embargo, la tasa de error aumenta y ahora está inundando nuestro registro de 24 horas.

Nuestro servidor está muy poblado y muchos usuarios inician sesión al mismo tiempo. La mayoría de estos usuarios no ven estas session_write_closeadvertencias. Algunos lo hacen, lo que hace que nos resulte casi imposible encontrar la causa y solucionarla.

Este es el mensaje de error completo:

Error message
E_WARNING: session_write_close(): Failed to write session data (files).    
Please verify that the current setting of session.save_path is correct        
(/opt/php55/var/lib/php/session-nginx)

Entonces hice una verificación, vi cuántos archivos hay en ese directorio 9431y cuáles eran los derechos -rw------- 1 nginx nginx.

No veo nada malo en mi configuración, derechos de archivos, etc.

Nos hemos quedado sin opciones. ¿Qué puedo hacer para resolver este problema? Actualmente afecta a <1% de nuestros usuarios, solo queremos mantener nuestra tarifa lo más baja posible.

Aquí hay una lista de mi configuración de php.ini.

Directive   Local Value Master Value
session.auto_start  Off Off
session.cache_expire    180 180
session.cache_limiter   nocache nocache
session.cookie_domain   no value    no value
session.cookie_httponly Off Off
session.cookie_lifetime 0   0
session.cookie_path /   /
session.cookie_secure   Off Off
session.entropy_file    /dev/urandom    /dev/urandom
session.entropy_length  32  32
session.gc_divisor  1000    1000
session.gc_maxlifetime  1440    1440
session.gc_probability  1   1
session.hash_bits_per_character 5   5
session.hash_function   0   0
session.name    PHPSESSID   PHPSESSID
session.referer_check   no value    no value
session.save_handler    files   files
session.save_path   /opt/php55/var/lib/php/session-nginx    /opt/php55/var/lib/php/session-nginx
session.serialize_handler   php php
session.upload_progress.cleanup On  On
session.upload_progress.enabled On  On
session.upload_progress.freq    1%  1%
session.upload_progress.min_freq    1   1
session.upload_progress.name    PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix  upload_progress_    upload_progress_
session.use_cookies On  On
session.use_only_cookies    On  On
session.use_strict_mode Off Off
session.use_trans_sid   0   0

Algunas estadísticas del servidor: CentOS 6.6 PHP 5.5.28 Nginx 1.6.2 ¡Cualquier ayuda es bienvenida!

Respuesta1

Con un servidor muy cargado, lo usaría memcached(¿tal vez incluso redis?) para el almacenamiento de sesiones. Entonces, si estuviera en su situación, probablemente lo configuraría por sí solo y luego vería si el problema había desaparecido fortuitamente.

Tampoco usaría la recolección de basura de sesión de PHP, que bloquea la recolección de basura de los trabajos de solicitud web. Configuraría mi propio trabajo para manejar eso, ya sea ejecutándolo desde cron o desde algún sistema de cola de trabajos.

¿Ya tiene algún tipo de sistema de limpieza de sesiones fuera de la recolección de basura de sesiones de PHP?

¿La velocidad a la que esto ocurre es el 0,1% del tiempo, lo que se alinearía con su session.gc_divisorconfiguración?

¿Sus procesos php se ejecutan como usuario de nginx? Es php en lugar de nginx el que realiza la limpieza según la session.gc_*configuración. Si php se ejecuta como nginx, eso es bueno en términos de acceso a los archivos de sesión de php, pero probablemente malo en términos de compartir una identificación de usuario con el servidor nginx.

Es posible que necesite el permiso de ejecución en ese directorio de sesión para que su recolección de basura pueda ver qué hay que limpiar.

También me preocuparía si no configura session.save_pathalgo específico para su aplicación. Eso significaría que si tiene varias aplicaciones que comparten el mismo directorio de sesión, cuando se ejecuta la recolección de basura, gana la aplicación con la caducidad más corta, limpiando las sesiones de la otra aplicación.

Respuesta2

La observación obvia que hice a partir de su pregunta es que tiene demasiado cuello de botella al intentar guardar archivos en /opt/php55/var/lib/php/session-nginx. Entonces, su solución es aliviar el cuello de botella, diagnosticando primero qué es lo que está fallando específicamente.
Suponiendo que esté corriendo, para escribir en el disco, y que los errores sean una señal de que se está rindiendo, esperaría errores de dmesg que muestren problemas al escribir en el disco. Si ese es el caso, puede escribir en la memoria u otras soluciones que equivalgan a un "disco" más rápido.
mc0e menciona memcached en lugar de usar save_handle=files, esa es una buena opción. Una alternativa a Memcached podría ser usar tmpfs, que esencialmente coloca la sesión en la memoria de todos modos (por lo que tiene tiempos de escritura rápidos), pero no necesita una aplicación nueva.
También haría la pregunta ¿qué tipo de sistema de archivos hay en /opt/php55/var/lib/php/session-nginx? No necesita todo el complejo registro en diario de ext3/4 para lo que es básicamente una operación de tipo mktmp. Es posible que desee crear una carpeta en /tmp y vincularla simbólicamente para garantizar una menor sobrecarga en la creación de archivos.
¿Cuál es la configuración del hardware? Si se trata de un solo disco sin almacenamiento en caché, debería ver problemas en dmesg si está alcanzando el límite de su rendimiento. Utilicé controladores AMCC Raid con Raid-1 en todos mis servidores. Si es Raid-1 (espejo), será rápido de leer, pero la velocidad de escritura dependerá de qué tan bien se implemente el raid (sé que AMCC puede distribuir escrituras entre discos en Raid-1, pero no en todas las implementaciones de RAID-1). hacer eso, sé que el software raid no lo hace). Mi antiguo jefe juraba por Raid-5 por esta razón, y siempre que sea un raid de hardware real (RAID-5 puede ser costoso para la CPU si no lo es), acelerará drásticamente el rendimiento del disco. Otra opción es un disco de estado sólido, pero realmente si vas por ese camino, te sugiero usar memcached o tmpfs, ya que más memoria siempre es un buen plan (sobre cualquier otro hardware nuevo).

Sin embargo, la solución más simple será crear /tmp/session-nginx y un enlace simbólico o montar /opt/php55/var/lib/php/session-nginx en /tmp/session-nginx/

Respuesta3

Parte de la pregunta es sobre la dificultad de rastrear ese tipo de errores, entonces puedo sugerir cerrar explícitamente la sesión en su código dentro de un bloque try/catch. Maneja la excepción, duerme y vuelve a intentarlo.

La otra parte de la pregunta describe un error de escritura que parece ser de naturaleza aleatoria. Esto no es lo que espero de permisos incorrectos. Sospecho que tienes demasiados archivos abiertos.

Hay algunas configuraciones que modificaría para ver qué sucede:

  1. aumentar el límite de archivos abiertosEs posible que tenga algún límite inferior establecido en alguna parte de su sistema operativo. Por ejemplo, mi portátil admite cientos de miles de archivos abiertos, pero sólo 4000 del mismo usuario.

  2. baje el maxrequestperchilds a 1000esto hará que cada servidor http se reinicie después de atender a 1000 clientes.

  3. reducir MaxClientsyaumentar ListenBacklog. Esto es muy, muy contradictorio, pero si configura MaxClients/Servers demasiado alto, muchos procesos lucharán por los recursos en su servidor y causarán cuellos de botella. Eso depende en gran medida del tipo de obstáculos que tengas. El mío son los servidores de bases de datos.

información relacionada