2010-12-02 20 views
25

ya que unas pocas horas nuestro servidor se bloquea cada vez que hace una session_start.session_start se cuelga

Para propósitos de prueba que he creado un script que se parece a esto:

<?php 
session_start(); 
?> 

Llamando desde la consola se bloquea y no puede ni siquiera ser detenido con Ctrl-C, sólo kill -9 obras. Lo mismo para llamarlo a través de Apache. /var/lib/php/session/ permanece vacío pero los permisos son absolutamente correctos, www puede escribir y también tiene permisos de lectura para todas las carpetas principales.

Según los administradores no se realizaron cambios en el servidor y no hay ningún código especial registrado para las sesiones. El servidor es CentOS 4 o 5 y ayer todo funcionaba perfectamente. Reiniciamos el servidor y actualizamos PHP, pero nada cambió.

Me he quedado sin ideas, alguna sugerencia?

ACTUALIZACIÓN

Hemos resuelto este problema al mover el proyecto a otro servidor, por lo que mientras el problema sigue existiendo en un servidor que no hay necesidad inmediata de una solución ya. Mantendré la pregunta abierta en caso de que alguien tenga una idea para otros que tengan un problema similar en el futuro.

+0

Compruebe los registros de errores del sistema: ¿hay suficiente espacio? ¿Sus archivos de registro no se desbordan? ¿No te estás quedando sin inodos? ¿Hay algún límite en la cantidad de archivos en/tmp/session o en cualquier lugar donde almacene sus archivos? – Piskvor

+0

Los archivos de registro no muestran ningún error y el almacenamiento está en un NFS. Otro servidor que accede al mismo NFS funciona para el proyecto. No hay límite en la cantidad de archivos de sesión. – dbemerlin

+0

La conexión entre el servidor A y NSF es cuestionable. Verifique la conexión nuevamente. – ajreal

Respuesta

22

Hay muchas razones para ello, aquí están algunos de ellos:

A. El archivo de sesión se pudo abrir exclusivamente. Cuando el bloqueo de archivos no se libera correctamente por el motivo que sea, está causando que session_start() se cuelgue infinitamente en futuras ejecuciones de scripts. Solución: utilizar session_set_save_handler() y asegúrese de que la función de escritura utiliza fopen($file, 'w') instead of fopen($file, 'x')

B. Nunca utilice lo siguiente en su archivo php.ini (archivo Entropie a "/dev/random"), esto hará que su session_start() para colgar:

<?php 
ini_set("session.entropy_file", "/dev/random"); 
ini_set("session.entropy_length", "512"); 
?> 

C. session_start() necesita un directorio para escribir.

Puede ejecutar Apache plus PHP en una cuenta de usuario normal. Apache tendrá que escuchar, por supuesto, otro puerto que no sea 80 (por ejemplo, 8080).

Asegúrese de hacer las siguientes cosas: - crear un directorio temporal PREFIX/tmp - poner en php.iniPREFIX/lib - editar php.ini y establecer session.save_path al directorio que acaba de crear

De lo contrario, las secuencias de comandos parecerán para 'colgar' en session_start().

+1

Después del reinicio, no debería haber ningún bloqueo y 'lsof' no mostraba ningún otro script PHP en ejecución. No cambiamos el archivo de entropía o la longitud. La ruta de la sesión existe y es grabable, por lo que C tampoco parece serlo. Movimos el proyecto a otro nodo que tiene una configuración idéntica y funciona allí de nuevo. Gracias por la respuesta, pero no parece ser el problema. – dbemerlin

+0

Intente utilizar un controlador de sesión personalizado no basado en archivo. – symcbean

+1

¿Puedes dar más detalles sobre la opción A? – danielson317

3

Tuve un problema extraño con esto yo mismo.

Estoy usando CentOS 5.5x64, PHP 5.2.10-1. Se colgó un archivo ANSI limpio en la raíz con nada más que session_start(). La sesión se estaba escribiendo en el disco y no se lanzaron errores. Simplemente colgó.

He intentado todo lo sugerido por Thariama, y ​​comprueba PHP compilar los ajustes etc.

Mi solución:

yum reinstall php; /etc/init.d/httpd restart 

Espero que esto ayude a alguien.

Para todos los quejándose de que los 30 segundos de inactividad sean inaceptables, este fue un problema inexplicable en una instalación de sistema operativo nueva y limpia, NO en una máquina de producción en ejecución. Esta solución NO se debe usar en un entorno de producción.

+0

Jup reinstalará mi php en mi servidor en vivo ejecutando más de 100 sitios web ;-) duh .. –

+0

@Wimpie reinstalar php y reiniciar httpd lleva unos 30 segundos incluso en un VPS de baja calidad. – csvan

+0

@csvan eso es exactamente 30 segundos de inactividad inaceptable –

5

si esto ayuda:

En mi escenario, session_start() estaba colgando al mismo tiempo que estaba usando el depurador XDebug dentro PhpStorm, el IDE, en Windows. Descubrí que había una causa clara: cada vez que eliminaba la sesión de depuración dentro de PHPStorm, la próxima vez que intentaba ejecutar una sesión de depuración, se bloqueaba el session_start().

La solución, si este es su caso, es asegurarse de reiniciar Apache cada vez que mata una sesión XDebug dentro de su IDE.

+0

Esta sugerencia me ayudó. Gracias. – Clutch

+0

Acabo de recibir este problema exacto. Tu solución ayuda. –

2

El problema: -

Iv experimentado (y fijos) el problema donde las sesiones basadas en archivos colgar la solicitud, y sesiones basadas en bases de datos perder la sincronización mediante el almacenamiento de datos de la sesión de fecha (como el almacenamiento de cada sesión guardar en el orden incorrecto).

Esto es causado por cualquier solicitud posterior que carga una sesión (solicitudes simultáneas), como ajax, video embebido donde el archivo de video se entrega mediante script php, archivo de recursos dinámicos (como script o css) entregado a través de script php, etc.

En las sesiones basadas en archivos, el bloqueo de archivo evita la escritura de la sesión, lo que causa un interbloqueo entre los hilos de solicitud simultáneos. En la sesión basada en base de datos, la última cadena de solicitud se completa.

La solución: -

Si su ajax o recurso guión de entrega doesnt necesidad de utilizar sesiones entonces más fácil de eliminar sólo el uso de la sesión de la misma.

De lo contrario será mejor que hacerse un café y hacer lo siguiente: -

  1. escritura o emplear un controlador de sesión (si no lo están haciendo ya) según http://www.php.net//manual/en/class.sessionhandler.php (muchos otros ejemplos disponibles a través de Google de búsqueda) .
  2. En su sesión de función de controlador de escritura() anteponer el código ...

    // processes may declare their session as read only ... 
        if(!empty($_SESSION['no_session_write'])) { 
          unset($_SESSION['no_session_write']); 
          return true; 
        } 
    
  3. En su ajax o recurso script php entrega añadir el código (después de iniciar la sesión) ...

    $_SESSION['no_session_write'] = true; 
    

que se dan cuenta de esto parece una gran cantidad de relleno alrededor de lo que debería ser una solución pequeña, pero, por desgracia, si es necesario tener la carga de peticiones simultáneas cada una sesión, entonces se requiere.

NOTA si su script ajax o de entrega de recursos realmente necesita escribir/guardar datos, entonces debe hacerlo en algún lugar que no sea la sesión, como la base de datos.

0

Para arrojar otra respuesta en la mezcla para los que van plátanos, tuve un session_start() muriendo solo en casos particulares y scripts. La razón por la que mi sesión estaba muriendo era en última instancia porque estaba almacenando un lote de datos después de un script particularmente intensivo, y finalmente la llamada a session_start() estaba agotando la configuración 'memory_limit' en php.ini.

Después de aumentar 'memory_limit', esas llamadas session_start() ya no mataban mi script.