Tengo un sistema Ubuntu 10.04 que ejecuta varias docenas de sitios Python Django usando mod_wsgi (modo integrado; elmodo más rápido, si está configurado correctamente). El rendimiento fluctúa mucho. A veces rápido, a veces con varios segundos de retraso. Los gráficos sobre el tabaquismo están por todos lados.
Recientemente, también agregué un proxy nginx para el contenido estático, con la esperanza de que solucione el rendimiento altamente fluctuante. Pero, aunque redujo significativamente la cantidad de solicitudes que Apache tiene que procesar, no ayudó con el problema principal.
Al hacer clic en sitios web mientras se ejecuta htop, se puede ver que a veces las solicitudes son casi instantáneas, mientras que a veces hace que Apache consuma el 100% de la CPU durante unos segundos. Realmente no entiendo de dónde viene esta fluctuación.
He configurado mpm_worker para Apache de esta manera:
StartServers 1
MinSpareThreads 50
MaxSpareThreads 50
ThreadLimit 64
ThreadsPerChild 50
MaxClients 50
ServerLimit 1
MaxRequestsPerChild 0
MaxMemFree 2048
1 servidor con 50 subprocesos, máximo 50 clientes. Munin y apache2ctl -t
ambos muestran una presencia constante de trabajadores; no se destruyen ni se crean todo el tiempo. Sin embargo, se comporta como tal.
Esteme dice que una vez que se crea un subintérprete, debe permanecer en la memoria, pero parece que los sitios tienen que recargarse todo el tiempo.
También tengo una caja nginx+gunicorn, que funciona bastante bien. Realmente me gustaría saber por qué Apache es tan aleatorio.
Esta es una configuración de host virtual:
<VirtualHost *:81>
ServerAdmin [email protected]
ServerName example.com
DocumentRoot /srv/http/site/bla
Alias /static/ /srv/http/site/static
Alias /media/ /srv/http/site/media
WSGIScriptAlias / /srv/http/site/passenger_wsgi.py
<Directory />
AllowOverride None
</Directory>
<Directory /srv/http/site>
Options -Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
- ubuntu 10.04
- Apache 2.2.14
- mod_wsgi 2.8
- nginx 0.7.65
Editar: puse un código en el archivo settings.py de un sitio que escribe la fecha en un archivo tmp cada vez que se carga. Ahora puedo ver que el sitio no se recarga aleatoriamente todo el tiempo, por lo que Apache debe mantenerlo en la memoria. Entonces, eso es bueno, excepto que no me acerca a una respuesta...
Editar: acabo de encontrar un error que también podría estar relacionado con esto:
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1049, in _execute_child
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
El servidor tiene 600 de 2000 MB libres, lo que debería ser suficiente. ¿Existe un límite establecido en Apache o WSGI en alguna parte?
Respuesta1
¿Ha intentado utilizar New Relic para intentar identificar si se trata de un problema en su aplicación web? Nivel gratuito disponible y también una prueba completa inicial. Descripción general de lo que puede ofrecerle en:
Si un problema específico con la aplicación web del servicio backend que se utiliza no se destaca como un problema, el informe de análisis de capacidad del servidor WSGI puede mostrar algo, lo que le indicará si se está quedando sin capacidad. También puede indicarle si está sobreaprovisionado y desperdiciando recursos, lo que en realidad es el caso con bastante frecuencia.
Por cierto, en general recomendaría no utilizar 50 subprocesos de solicitud en un solo proceso. Es mejor utilizar unos 5 subprocesos y múltiples procesos. Sin embargo, exactamente lo que es mejor realmente depende de la aplicación específica, de si está realizando una gran cantidad de trabajo vinculado a la CPU y de cuánto tiene que manejar solicitudes de ejecución prolongada. Si servir una gran cantidad de archivos estáticos a través del mismo Apache también puede afectarlo, y el modo demonio de mod_wsgi posiblemente sea incluso una mejor solución general.
También tienes una versión mod_wsgi muy antigua, aunque no creas que eso causaría un problema.
Finalmente, para evitar problemas con algunos módulos de extensión C de terceros para Python, si esta es la única aplicación WSGI en ese servidor, configure:
WSGIApplicationGroup %{GLOBAL}
Respuesta2
Lo arreglé. Convertí todos los sitios de producción para usar su propio proceso (y también todos los sitios de desarrollo juntos en un solo proceso), en modo demonio. Los gráficos de Smokeping son mucho mejores ahora. El rendimiento es estable.
Esto todavía me deja sin saber por qué el modo integrado tuvo estos problemas, porque hasta donde puedo decir, no tuve ningún proceso de creación/destrucción, pero al menos tengo un servidor que funciona mejor.
Editar:
Como ejemplo de configuración de un sitio Apache:
WSGIDaemonProcess mysite12 processes=1 threads=10 display-name=%{GROUP}
WSGIProcessGroup mysite12
Y luego, para los sitios de baja prioridad, pongo esto wsgi.conf
:
WSGIDaemonProcess developmentsites processes=1 threads=15 display-name=%{GROUP}
Y luego en una configuración de Apache:
WSGIProcessGroup developmentsites
Mire la diferencia (también debido al proxy nginx):