2009-11-09 10 views
22

Cuando actualizo el código en mi sitio web, (naturalmente) reinicio mi instancia de Apache para que los cambios surtan efecto.Acelerando la carga de la primera página en django

Desafortunadamente, la primera página servida por cada instancia de apache es bastante lenta mientras carga todo en RAM por primera vez (5-7 segundos para este sitio en particular).

Las solicitudes posteriores solo demoran de 0,5 a 1,5 segundos, por lo que me gustaría eliminar este efecto para mis usuarios.

¿Hay una mejor manera de conseguir todo cargado en la memoria RAM que no hacer una wget x veces (donde x es el número de instancias de Apache definidos por ServerLimit en mi http.conf)

escribir un guión de reinicio que se reinicia Apache y ejecuta wget 5 veces me parece un poco hacky.

Gracias!

+4

En realidad, escribir un script de reinicio que reinicie apache y ejecute 'wget' 5 veces me parece un enfoque razonable. –

+2

Aunque es posible que tengas que tener cuidado de que cada una de esas llamadas a 'wget' se maneje por un proceso diferente; probablemente tendrás que cargarlo una buena cantidad de veces para estar seguro. –

+1

Lo he probado y la configuración de Apache en webfaction (donde se aloja la aplicación) hace un ciclo a través de las instancias, por lo que 5 'wget' hace el truco – Jiaaro

Respuesta

31

El valor por defecto para Apache/mod_wsgi es sólo el código de aplicación de carga al primer requerimiento de un proceso que requiere que las aplicaciones. Entonces, el primer paso es configurar mod_wsgi para precargar su código cuando se inicia el proceso y no solo la primera solicitud. Esto se puede hacer en mod_wsgi 2.X usando la directiva WSGIImportScript.

Suponiendo modo demonio, que es mejor opción de todas formas, esto significa que tendría algo como:

# Define process group. 

WSGIDaemonProcess django display-name=%{GROUP} 

# Mount application. 

WSGIScriptAlias//usr/local/django/mysite/apache/django.wsgi 

# Ensure application preloaded on process start. Must specify the 
# process group and application group (Python interpreter) to use. 

WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django application-group=%{GLOBAL} 

<Directory /usr/local/django/mysite/apache> 

    # Ensure application runs in same process group and application 
    # group as was preloaded into on process start. 

    WSGIProcessGroup django 
    WSGIApplicationGroup %{GLOBAL} 

    Order deny,allow 
    Allow from all 
</Directory> 

Cuando haya realizado un cambio de código, en lugar de toque el archivo de script WSGI, que sólo está marcada en la próxima solicitud, envíe una señal SIGINT a los procesos en el grupo de proceso daemon en su lugar.

Con la opción 'display-name' de WSGIDaemonProcess, puede identificar qué procesos utilizando el programa BSD style 'ps'. Con 'display-name' en '% {GROUP}', la salida 'ps' debe mostrar '(wsgi: django)' como nombre del proceso. Identifique el ID del proceso y haga:

kill -SIGINT pid 

Cambie 'pid' con el ID del proceso real. Si hay más de un proceso en el grupo de procesos daemon, envíe señales a todos ellos.

No estoy seguro si se puede usar 'killall' para hacer esto en un solo paso. Tuve problema de hacer que en MacOS X.

En 3.X mod_wsgi la configuración puede ser más simple y se puede utilizar en su lugar:

# Define process group. 

WSGIDaemonProcess django display-name=%{GROUP} 

# Mount application and designate which process group and 
# application group (Python interpreter) to run it in. As 
# process group and application group named, this will have 
# side effect of preloading application on process start. 

WSGIScriptAlias//usr/local/django/mysite/apache/django.wsgi \ 
    process-group=django application-group=%{GLOBAL} 

<Directory /usr/local/django/mysite/apache> 
    Order deny,allow 
    Allow from all 
</Directory> 

Es decir, no hay necesidad de utilizar Directiva WSGIImportScript separada como proceso específico lata grupo y grupo de aplicaciones como argumentos para WSGIScriptAlias ​​en cambio con efecto secundario que precargará la aplicación.

3

¿Cómo estás ejecutando Django (mod_python vs mod_wsgi)?

Si está ejecutando mod_wsgi (en modo daemon), no es necesario reiniciar Apache para volver a cargar su aplicación. Todo lo que necesita hacer es actualizar el mtime de su script wsgi (que se hace fácilmente con touch). documentación

de mod_wsgi tiene una explicación muy detallada del proceso:

ReloadingSourceCode

+0

¡Me he estado preguntando por qué no estaba recargando la aplicación! Tendré que reemplazar mi script de reinicio con un guión táctil wsgi :) ¿Eso resolverá mi primer problema de carga? o ¿todavía necesito wget? – Jiaaro

+0

Reducirá el tiempo empleado en la primera carga, pero no lo eliminará. –

Cuestiones relacionadas