2009-08-03 15 views
9

He Django ejecuta a través de WSGI como esto:cómo dejar de WSGI de colgar Apache

<VirtualHost *:80> 
    WSGIScriptAlias//home/ptarjan/django/django.wsgi 
    WSGIDaemonProcess ptarjan processes=2 threads=15 display-name=%{GROUP} 
    WSGIProcessGroup ptarjan 
    Alias /media /home/ptarjan/django/mysite/media/ 
</VirtualHost> 

Pero si en Python que hago:

def handler(request) : 
    data = urllib2.urlopen("http://example.com/really/unresponsive/url").read() 

el conjunto se bloquea el servidor Apache y hasta ahora no responde con este backtrace

#0 0x00007ffe3602a570 in __read_nocancel() from /lib/libpthread.so.0 
#1 0x00007ffe36251d1c in apr_file_read() from /usr/lib/libapr-1.so.0 
#2 0x00007ffe364778b5 in ??() from /usr/lib/libaprutil-1.so.0 
#3 0x0000000000440ec2 in ??() 
#4 0x00000000004412ae in ap_scan_script_header_err_core() 
#5 0x00007ffe2a2fe512 in ??() from /usr/lib/apache2/modules/mod_wsgi.so 
#6 0x00007ffe2a2f9bdd in ??() from /usr/lib/apache2/modules/mod_wsgi.so 
#7 0x000000000043b623 in ap_run_handler() 
#8 0x000000000043eb4f in ap_invoke_handler() 
#9 0x000000000044bbd8 in ap_process_request() 
#10 0x0000000000448cd8 in ??() 
#11 0x0000000000442a13 in ap_run_process_connection() 
#12 0x000000000045017d in ??() 
#13 0x00000000004504d4 in ??() 
#14 0x00000000004510f6 in ap_mpm_run() 
#15 0x0000000000428425 in main() 

en Debian Apache 2.2.11-7.

Del mismo modo, podemos estar protegidos contra:

def handler(request) : 
    while (1) : 
     pass 

En PHP, me gustaría establecer límites de tiempo y memoria.

Respuesta

13

No es el 'deadlock-timeout' que desea según lo especificado por otro, que es para un propósito muy especial que no ayudará en este caso.

En cuanto a tratar de usar las características de mod_wsgi, en su lugar desea la opción 'inactivity-timeout' para la directiva WSGIDaemonProcess.

Incluso entonces, esta no es una solución completa. Esto se debe a que la opción 'inactivity-timeout' es específicamente para detectar si ha cesado todo el proceso de solicitud por un proceso de daemon, no es un tiempo de espera por solicitud. Solo equivale a un tiempo de espera por solicitud si los procesos de daemon tienen un solo subproceso. Además de ayudar a despegar un proceso, la opción también tendrá el efecto secundario de reiniciar el proceso del daemon si no llegan solicitudes en ese momento.

En resumen, no hay forma en que el nivel de mod_wsgi tenga tiempos de espera por solicitud, esto se debe a que no existe una manera real de interrumpir una solicitud, o un hilo, en Python.

Lo que realmente necesita implementar es un tiempo de espera excedido en la solicitud HTTP en el código de la aplicación. No estoy seguro de dónde está y si ya está disponible, pero haga una búsqueda en Google de 'timeout urllib2 socket'.

+0

Entonces, ¿no hay forma de que python se ejecute de manera robusta? Sí ... Parece que debería presentar una solicitud de función mod_wsgi. –

+1

No tiene sentido pedir una solicitud de función mod_wsgi. La incapacidad de interrumpir un hilo que maneja una solicitud es una limitación de Python. –

+0

¿No tiene http://docs.python.org/library/thread.html#thread.interrupt_main la capacidad de interrumpir un hilo? ¿O me estoy perdiendo algo? –

3

Si entiendo bien la pregunta, quiere proteger Apache del bloqueo cuando ejecuta algunos scripts aleatorios de personas. Bueno, si está ejecutando código que no es de confianza, creo que tiene otras cosas de qué preocuparse que son peores que apache.

Dicho esto, puede usar algunas directivas de configuración para ajustar un entorno más seguro. Estos dos abajo son muy útiles:

  • WSGIApplicationGroup - Establece la aplicación aplicación WSGI grupo pertenece. Permite separar las configuraciones para cada usuario: todas las aplicaciones WSGI dentro del mismo grupo de aplicaciones se ejecutarán dentro del contexto del mismo intérprete de Python del proceso que maneja la solicitud.

  • WSGIDaemonProcess - Configura un proceso de daemon distinto para ejecutar aplicaciones. Los procesos del daemon se pueden ejecutar como un usuario diferente al que los procesos secundarios de Apache normalmente se ejecutarían. Esta directiva acepta una gran cantidad de opciones útiles, Voy a enumerar algunas de ellas:

    • user=name | user=#uid, group=name | group=#gid:

      Define el usuario y nombre de grupo o nombre de UNIX UID numérico de usuario o grupo GID del usuario/agrupe que los procesos del daemon se deben ejecutar como.

    • stack-size=nnn

      La cantidad de memoria virtual en bytes que debe asignarse para la pila que corresponde a cada hilo creado por mod_wsgi en un proceso daemon.

    • deadlock-timeout=sss

      define el número máximo de segundos que pueden pasar antes de que el proceso de demonio es apagado y se reinicia después de que se ha detectado un interbloqueo potencial en el GIL Python. El valor predeterminado es 300 segundos.

Puede leer más acerca de las directivas de configuración here.

+0

Entonces, con el tiempo de espera de 300 segundos, ¿eso significa que el proceso de apache debería haber matado a mi demonio python y haberlo reiniciado? Porque todo el apache estaba bloqueado e inutilizable. ¿Necesito más hilos? ¿Menos? Más procesos? –