2012-09-26 21 views
11

Cualquier servidor web podría tener que manejar una gran cantidad de solicitudes al mismo tiempo. Como el intérprete python en realidad tiene una restricción GIL, ¿cómo se implementa la concurrencia?¿Cómo supera un servidor web python GIL

¿Utilizan procesos múltiples y utilizan IPC para compartir estados?

+4

¿Qué estado comparte? El objetivo de las solicitudes web es que cada una es independiente, no hay un estado compartido. –

Respuesta

2

Como es normal. El servicio web está principalmente vinculado a E/S, y el GIL se libera durante las operaciones de E/S. Por lo tanto, el enhebrado se utiliza sin adaptaciones especiales, o se usa un bucle de eventos (como Torcido).

+1

No estoy hablando de esperar/recibir una solicitud. Estoy hablando de manejarlos. Por ejemplo, si recibo una solicitud, es posible que tenga que hacer algún procesamiento, como comprobar varias solicitudes POST o GET, que generalmente se escribe como código python. Entonces, ¿cómo Python Interpreter ejecutará estos bloques de código al mismo tiempo, ya que tiene restricción GIL. –

+2

Esto es simplemente falso. No todas las cargas de trabajo están vinculadas a IO. Es completamente común ver servidores web con CPU maximizadas. Depende de la aplicación que se está ejecutando. – usr

1

Generalmente tiene muchos trabajadores (es decir, gunicornio), cada uno de los cuales se envía con solicitudes independientes. Todo lo demás (relacionado con la concurrencia) es manejado por la base de datos por lo que se abstrae de usted.

No es necesario IPC, sólo se necesita un "única fuente de la verdad", que será el RDBMS, un servidor caché (Redis, memcached), etc.

1

En primer lugar, las solicitudes pueden ser manejado de forma independiente. Sin embargo, los servidores desean simultáneamente manejarlos para mantener el número de solicitudes que se pueden manejar por tiempo como máximo.

La implementación de este concepto de concurrencia depende del servidor web.

Algunas implementaciones pueden tener un número fijo de subprocesos o procesos para gestionar solicitudes. Si todos están en uso, las solicitudes adicionales tienen que esperar hasta que se manejen.

Otra posibilidad es que se genere un proceso o subproceso para cada solicitud. Engendrar un proceso para cada solicitud lleva a una memoria absurda y una sobrecarga de la CPU. Engendrar hilos ligeros es mejor. Al hacerlo, puede atender a cientos de clientes por segundo. Sin embargo, los subprocesos también generan una sobrecarga de administración, que se manifiesta en una gran cantidad de memoria y consumo de CPU.

Para servir a miles de clientes por segundo, una arquitectura basada en eventos basada en corutinas asíncronas es una solución de vanguardia. Permite que el servidor sirva a los clientes a un ritmo elevado sin generar tropezones de hilos. En el Wikipedia page of the so-called C10k problem encontrará una lista de servidores web. Entre ellos, muchos hacen uso de esta arquitectura.

Coroutines están disponibles para Python, también. Mira en http://www.gevent.org/. Es por eso que una aplicación Python WSGI basada en, por ejemplo, uWSGI + gevent, es una solución extremadamente eficaz.

+0

"Generar un proceso para cada solicitud lleva a una memoria absurda y una sobrecarga de la CPU". Esto es completamente dependiente del SO. –

+0

@ IgnacioVazquez-Abrams: ¿para qué sistema operativo esto no es cierto ("absurdo" en comparación con la sobrecarga de enhebrar o corutinas)? –

+0

No es que no sea cierto, es que la definición exacta de "absurdo" varía; Windows es una gran pila humeante de excrementos benditos cuando se trata de iniciar nuevos procesos, pero los nices tienden a ser un poco más ligeros en comparación. –

Cuestiones relacionadas