2012-02-20 37 views
9

Nuestra aplicación php, que se ejecuta bajo apache, ocasionalmente está tratando de bloquear un archivo de sesión eliminado, esto bloquea el proceso de apache y, finalmente, nos quedamos sin procesos.php está bloqueando un archivo de sesión eliminado

La evidencia:

strace : flock(89, LOCK_EX     -----stuck in flock for File Descriptor 89 

y luego:

lsof, para el mismo proceso:

httpd 22161 apache 89u ... /var/lib/php/session/sess_mf7svvirg7rbu9l0m5999pm6h4 (deleted) 

Alguna idea de por qué esto está ocurriendo? ¿Y qué podemos hacer para prevenirlo?

+2

a) Esta pregunta es probablemente mejor dirigida hacia http://webmasters.stackexchange.com/ b) ¿Quién borró el archivo de la sesión? ¿Tú o PHP? ¿Hace cuánto tiempo fue eliminado? ¿Estás seguro de que se ha eliminado y no está bloqueado por otro proceso? – DaveRandom

+1

¿está utilizando la gestión de sesiones de php o un controlador de sesión personalizado? – dqhendricks

+0

¿Alguna información viene a través del registro de errores que puede relacionarse con el porqué de esto? –

Respuesta

0

No tengo idea del porqué de su caso.

Este question han conseguido algunas buenas sugerencias ...

¿Ha intentado reinstalar el medio ambiente, o el traslado a un servidor diferente? ¿Funcionará si invalida el manejador de sesión predeterminado y usa fopen ($ file, 'w') en lugar de fopen ($ file, 'x')?

También la solución de implementar un controlador de sesión basado en una base de datos, hay un millón o más de guías para configurar un "gestor de sesión php y mysql", por ejemplo.

1

¿Hay alguna necesidad tremenda (cliente) de borrar el archivo de sesión? No deberías hacer eso. PHP en sí mismo implementa un mecanismo de recolección de basura para eliminar archivos de sesión desaparecidos. Va a ser much more efficient que cualquier otra cosa que puedas escribir usando PHP.

que puede utilizar:

  1. session_destroy - Destruye todos los datos a una sesión
  2. session_unset - Libre de todas las variables de sesión

Y hacer session_start() de nuevo.

Ver más here.

Actualización:

PHP es un motor de scripting muy limpio, que no deja basura en su sistema! Los archivos de sesión se eliminan automáticamente después de que se alcanza el tiempo de espera de la sesión. session-timeout puede ser caso con su sistema, creo que sí. Por lo tanto, si el tiempo de espera se establece en 20 minutos, los archivos se eliminarán 20 minutos después del último acceso. Lo mismo para la galleta. Cada vez que se solicita una página, la cookie-ttl se establece ahora en + 20 minutos.

echa un vistazo a algunos de los configuration directives. Las probabilidades indican que ha establecido gc_maxlifetime en un valor muy alto, y simplemente no han alcanzado el límite de "caducidad" para que se recopile automáticamente. Debe verificar sus aplicaciones para asegurarse de que no estén estableciendo valores extraños para la configuración de la sesión (usando ini_set()) durante el tiempo de ejecución.

PHP tiene un algoritmo interno que se ejecuta en session_start() que decide si debe ejecutar una limpieza de basura y eliminar archivos de sesión antiguos.Por motivos de rendimiento, creo que la probabilidad predeterminada de hacer una ejecución cada vez es del 1%, por lo que, en promedio, se iniciará una rutina de recolección de basura una vez cada 100 llamadas a session_start(). Si encuentra que esto no es suficiente, puede elevar la configuración gc_divisor a algo superior a 1.

+0

No creo que lo haga deliberadamente ... la pregunta es por qué PHP está intentando eliminar el archivo de sesión. –

+0

He leído 'de vez en cuando está intentando bloquear un archivo de sesión eliminado'. Así que esa es mi respuesta. Entonces la principal preocupación es qué código está tratando de eliminar el archivo de sesión. –

+0

Si el OP ya sabía qué era lo que está intentando bloquear un archivo de sesión eliminado, entonces no hay duda. –

0

Did ha intentado leer esos 2 errores abiertos?

https://bugs.php.net/bug.php?id=47640 https://bugs.php.net/bug.php?id=32092

intenta llamar a session_write_close() (fea solución temporal) como su última línea o para actualizar PHP.

3

He tenido un problema con síntomas idénticos al suyo, excepto si el archivo de sesión se eliminó o no era irrelevante (y puede serlo también para usted) ¿Tiene evidencia de que la eliminación del archivo de sesión está relacionada con el flock ?).

En mi caso, fue una condición de carrera para el acceso al mismo archivo de sesión entre los dos guiones:

  1. /page1.php ejecuta bien cuando está cargado. Incluye javascript que hace un XMLHttpRequest a /background.php.
  2. Cuando se accede a /background.php, se ejecuta readfile(http://remote.url), que es una URL inexistente.
  3. Al navegar a /page2.php, la secuencia de comandos está detenida. Una cadena muestra flock(89, LOCK_EX, e lsof indica que está esperando el acceso de lectura/escritura en un archivo de sesión.

En este escenario, tanto /page2.php y /background.php están ambos esperando en el mismo archivo de sesión, pero éste fue incapaz de hacerlo, ya que se llevó a cabo a la espera de la readfile() de tiempo de espera. Tengo esto en un php_error_log:

PHP Warning: readfile(http://remote.url): failed to open stream: Connection timed out in […]/background.php on line […] 

Así que el problema era con un guión completamente diferente que el culpable percibido.

Puede comprobar si este problema rápidamente por grepping todos los archivos abiertos para el archivo de sesión php para ver qué proceso httpd lo está utilizando:

$ sudo lsof | grep sess_it9q6kkvf83gcj72vu05p9fcad7 
httpd  31325 apache 74u  REG    8,5  410 11634061 /var/lib/php/session/sess_it9q6kkvf83gcj72vu05pfa543 
httpd  31632 apache 74uW  REG    8,5  410 11634061 /var/lib/php/session/sess_it9q6kkvf83gcj72vu05pfa543 

Si dos procesos httpd acceden al mismo archivo de sesión, probablemente este es tu problema. Ahora se puede ver que estos procesos están haciendo con strace, o en mi caso fue suficiente para utilizar apachectl fullstatus:

$ sudo apachectl fullstatus | grep 31632 
5-7 31632 0/1/1169 _ 0.05 6  30692 0.0 0.02 3.45 111.222.333.444 www.example.com.com  /background.php 
Cuestiones relacionadas