2010-01-07 14 views
7

Varios scripts Perl (Server Side Includes) llaman a un módulo Perl con muchas funciones en un sitio web. EDITAR: Los scripts están utilizando use lib para hacer referencia a las bibliotecas desde una carpeta. Durante períodos ocupados, los scripts (no las bibliotecas) se vuelven zombis y sobrecargan el servidor.¿Cómo puedo evitar zombies en las secuencias de comandos Perl CGI que se ejecutan en Apache 1.3?

Las listas de servidores:

319 ?  Z  0:00 [scriptname1.pl] <defunct>  
320 ?  Z  0:00 [scriptname2.pl] <defunct>  
321 ?  Z  0:00 [scriptname3.pl] <defunct> 

que tienen cientos de ejemplos de cada uno.

EDIT: No estamos utilizando tenedor, sistema o ejecutivo, aparte forman la directiva SSI

<!--#exec cgi="/cgi-bin/scriptname.pl"--> 

Por lo que yo sé, en este caso httpd en sí será el propietario del proceso. MaxRequestPerChild se establece en 0, lo que no debe permitir que los padres fallezcan antes de que el proceso hijo haya finalizado.

Hasta ahora hemos pensado que suspender temporalmente algunas de las secuencias de comandos ayuda al servidor a hacer frente a los procesos difuntos y evitar que caiga, sin embargo, los procesos zombies aún se están formando sin lugar a dudas. Aparentemente gbacon parece ser lo más cercano a la verdad con su teoría de que el servidor no puede hacer frente a la carga.

¿Qué podría llevar a httpd a abandonar estos procesos? ¿Existe alguna práctica recomendada para evitar que esto suceda?

Gracias

Respuesta: El punto va a Rob. Como él dice, los scripts CGI que generan SSI no tendrán esos SSI manejados. La evaluación de SSI ocurre antes de la ejecución de CGI en el ciclo de solicitud de Apache 1.3. Esto se solucionó con Apache 2.0 y versiones posteriores para que los CGI puedan generar comandos de SSI.

Como estábamos ejecutando Apache 1.3, por cada vista de página los SSI se convirtieron en procesos difuntos. Aunque el servidor intentaba borrarlos, estaba demasiado ocupado con las tareas en ejecución para poder tener éxito. Como resultado, el servidor se cayó y dejó de responder. Como una solución a corto plazo, revisamos todos los SSI y trasladamos algunos de los procesos al lado del cliente para liberar recursos del servidor y darle tiempo de limpieza. Más tarde nos actualizamos a Apache 2.2.

+9

necesita tirar una bomba de tubo –

+5

La escopeta de doble cañón también funciona bien. – Nate

+0

No les dejes comer tu cerebro también. – Hai

Respuesta

2

Acabo de ver su comentario de que está ejecutando Apache 1.3 y que puede estar asociado con su problema.

SSI pueden ejecutar CGI. Pero los scripts CGI que generan SSI no tendrán esos SSI manejados. La evaluación de SSI ocurre antes de la ejecución de CGI en el ciclo de solicitud de Apache 1.3. Esto se solucionó con Apache 2.0 y versiones posteriores para que los CGI puedan generar comandos de SSI.

Como he sugerido anteriormente, intente ejecutar sus scripts por su cuenta y eche un vistazo a la salida. ¿Están generando SSI?

Edit: ¿Ha intentado iniciar un guión CGI Perl trivial simplemente para imprimir una respuesta HTTP tipo Hello World?

Entonces si esto funciona añadir un triviales directivas SSI como

<!--#printenv --> 

y ver qué pasa.

Editar 2: Acabo de darme cuenta de lo que probablemente está pasando. Los zombis ocurren cuando un proceso secundario sale y no se cosecha. Estos procesos están dando vueltas y usando lentamente los recursos dentro de la tabla de procesos. Un proceso sin un padre es un proceso huérfano.

¿Está realizando procesos en su script de Perl? Si es así, ¿ha agregado una llamada a waitpid() al padre?

¿También obtuvo la salida correcta dentro del script?

CORE::exit(0); 
+0

Ejecuté todas las secuencias de comandos a través del depurador y eliminé todos los errores y advertencias. Están generando salida correctamente. Estábamos a punto de actualizar a 2.0 de todos modos. ¿Crees que eso ayudaría? –

+0

Ok. Buen trabajo con el depurador para eliminar todos los errores y advertencias. ¿Alguno de sus CGI de Perl se está ejecutando satisfactoriamente hasta su finalización? –

+0

Como dije, funcionan perfectamente. Además del hecho de que se convierten en zombies, funcionan perfectamente. –

7

Más tirita de las mejores prácticas, pero a veces puede salirse con la sencilla

$SIG{CHLD} = "IGNORE"; 

De acuerdo con la perlipc documentation

En la mayoría de las plataformas Unix, el CHLD (a veces también conocido como CLD) la señal tiene un comportamiento especial con respecto a un valor de 'IGNORE'. Establecer $SIG{CHLD} en 'IGNORE' en una plataforma de este tipo tiene el efecto de no crear procesos zombie cuando el proceso principal falla al wait() en sus procesos secundarios (es decir, los procesos secundarios se cosechan automáticamente). Llamar al wait() con $SIG{CHLD} establecido en 'IGNORE' generalmente devuelve -1 en dichas plataformas.

Si se preocupan por los estados de salida de los procesos secundarios, es necesario recogerlas (comúnmente conocida como la "cosecha") o llamando waitwaitpid. A pesar del nombre espeluznante, un zombie es simplemente un proceso secundario que ha salido pero cuyo estado aún no se ha cosechado.

Si los programas Perl en sí son los procesos hijos se conviertan en zombis, eso significa sus padres (los que se bifurcan a-y-olvidar su código) tienen que limpiar ellos mismos. Un proceso no puede evitar convertirse en zombie.

+0

Muchas gracias G. No estoy diciendo que entiendo cómo funciona, pero leeré más al respecto. Supongo que CHLD va al script de llamada. ¿Está bien? –

+5

waitpid (-1, WNOHANG) no se bloqueará, por lo que se puede llamar periódicamente para recopilar el estado de salida hijo. Use un bucle como este para cosechar todos sus zombies: while (($ pid = waitpid (-1, WNOHANG))> 0) ... –

+0

@G Berdal ¿Cómo se están iniciando sus scripts? ¿Controlas ese código? –

0

Como usted tiene todos los bits, le sugiero que ejecute los scripts individuales de a uno por vez desde la línea de comandos para ver si puede detectar los que están colgando.

¿La lista de una ps muestra un número desmedido de instancias de una secuencia de comandos en particular?

¿Estás ejecutando los CGI usando mod_perl?

Editar: Acabo de ver sus comentarios sobre SSI. No olvide que las directivas de SSI pueden ejecutar las secuencias de comandos de Perl. Echar un vistazo para ver qué están tratando de ejecutar los CGI?

¿Dependen de otro servidor o servicio?

+0

He visto los que están colgando. Casi todos los SSI en la página web se convierten en múltiples instancias de zombies. Están llamando a una biblioteca para funciones. Lo que no estoy seguro acerca de quién cuenta como padre de estos? –

+0

El proceso que llamó SSI o CGI es su padre. Podría intentar usar 'ps' para buscar el ppid (id del proceso padre) y luego ver cuál es ese proceso, pero no estoy seguro si' ps' devolverá un ppid para zombies. (Parece que debería ser así, dado que el zombi tiene que saber quién se supone que debe cosecharlo, simplemente no he verificado que funcione). Para mí, la salida de 'ps -l' incluye ppid; verifique su página man local si su 'ps' se comporta de manera diferente. –

+0

@Dave, cuando un proceso es un zombi no tiene ppid por definición. –

Cuestiones relacionadas