2010-05-08 13 views
6

EDIT: Actualización - desplazarse hacia abajo
EDIT 2: Actualización - problema resuelto PHP ejecutándose como una aplicación FastCGI (php-cgi) - ¿cómo emitir solicitudes simultáneas?


Algunos antecedentes:

estoy escribiendo mi propio servidor web en Java y un par Hace unos días pregunté por SO cómo exactamente Apache interactúa con PHP, así que puedo implementar el soporte de PHP. Aprendí que FastCGI es el mejor enfoque (ya que mod_php no es una opción). Así que he examinado la especificación del protocolo FastCGI y he logrado escribir un contenedor FastCGI que funciona para mi servidor. He probado phpinfo() y funciona, de hecho, todas las funciones de PHP parecen funcionar bien (publicar datos, sesiones, fecha/hora, etc.).

Mi servidor web puede atender solicitudes concurrentemente (es decir, user1 puede recuperar file1.html al mismo tiempo que user2 solicitando some_large_binary_file.zip), lo hace generando un nuevo hilo Java para cada solicitud de usuario (que termina cuando se completa o la conexión del usuario con el cliente se cancela).

Sin embargo, no puede tratar con 2 (o más) solicitudes FastCGI al mismo tiempo. Lo que hace es ponerlos en cola, de modo que cuando la solicitud 1 se completa inmediatamente después, comienza a procesar la solicitud 2. Probé esto con 2 páginas PHP, una contiene sleep (10) y la otra phpinfo().

¿Cómo voy a tratar con múltiples solicitudes, como sé que se puede hacer (PHP en IIS se ejecuta como FastCGI y puede tratar con múltiples solicitudes muy bien).

algo más de información:

estoy codificante bajo las ventanas y mi archivo por lotes utilizado para ejecutar php-cgi.exe contiene:

set PHP_FCGI_CHILDREN=8 
set PHP_FCGI_MAX_REQUESTS=500 
php-cgi.exe -b 9000 

pero no desovan 8 niños, el servicio simplemente termina después de 500 solicitudes.

I han realizado investigaciones y de Wikipedia: (. Es decir, múltiples solicitudes a través de una única conexión)

procesamiento de múltiples solicitudes simultáneamente se consigue ya sea por utilizando una sola conexión con multiplexación interna y/o al utilizar múltiples conexiones

Ahora, claramente, las conexiones múltiples no me funcionan, ya que cada vez que un cliente solicita sts algo que involucra FastCGI crea un nuevo socket para la aplicación FastCGI, pero no funciona al mismo tiempo (los pone en cola).

Sé que la multiplexación interna de solicitudes FastCGI bajo la misma conexión se logra al emitir cada solicitud FastCGI única con un request ID diferente. (vea también los últimos 3 párrafos del encabezado 'El protocolo de comunicación' en this article).

No he probado esto, pero ¿cómo podría implementarlo?Lo tomo Necesito algún tipo de subproceso de FastCGI Java que contiene un Mapa de algún tipo y una función estática que puedo usar para agregar solicitudes. Luego, en la función run() de Thread tendría un ciclo while y para cada ciclo verificaría si el mapa contiene nuevas solicitudes, de ser así, les asignaría una ID de solicitud y las escribiría en la transmisión FastCGI. Y luego espere la entrada, etc., etc. Como puede ver, esto se vuelve demasiado complicado.

¿Alguien sabe la forma correcta de hacer esto? O cualquier pensamiento en absoluto? Muchas gracias.

Nota, si es necesario, puedo suministrar el código para mi envoltorio FastCGI.


actualización:

Básicamente, he descargado nginx y configurarlo para usar PHP como una aplicación FastCGI y que también sufrieron el mismo problema que mi servidor. No podría manejar solicitudes concurrentes de PHP. Esto me lleva a creer que mi código es, de hecho, correcto. Entonces algo anda mal con PHP o no lo estoy configurando correctamente. Tal vez sea porque estoy usando Windows porque algunos usuarios de lighttpd afirman que Windows no puede manejar FastCGI correctamente (esto no tiene mucho sentido). Instalaré Linux algún día pronto e informaré cualquier progreso con eso.

+0

Muy bien, me quedé con este problema por un día, y difícil de entender lo que sucede en el sueño() de PHP afectará a otro proceso, gracias por su respuesta y compartir. – ykc

Respuesta

6

Bien, logré encontrar la causa del problema. No era mi código en absoluto. Es PHP, no puede generar php-cgi adicionales en Windows cuando se ejecuta como modo FastCGI, en Linux funciona perfectamente, simplemente apunté mi servidor a mi IP de Linux Box y no tuve problemas con las solicitudes de FCGI concurrentes. Apesta, pero supongo que así es ...

Miré más profundamente en el código fuente de PHP después de eso y encontré que la sección de código que responde a PHP_FCGI_CHILDREN ha sido encapsulada por #ifndef WIN32 Entonces los desarrolladores deben tenga en cuenta el problema

2

Hola, esto llega un poco tarde, he escrito un generador para php-cgi.exe en Windows, no perfecto, pero podría ser lo que necesitabas. Verifíquelo al here.

+0

¡Oh, muy bien, voy a echar un vistazo a eso! –

+0

halleluya man, después de 2 días de googlear extensamente y darse cuenta de que php-cgi.exe puede servir 1 conexión simultánea que estaba desesperado por desarrollar localmente en apache y en el servidor tiene nginx, pero quería tener la misma configuración en ambos entornos. entonces tu solución ayudó. Por cierto, solo funciona con activepython, porque tiene win32processes, el python estándar no tiene esa lib – Skyzer

2

re: desove-php script en Python ...

Gracias @nosam que realmente ayudó.
Para aquellos que quieran conseguir que funcione con rapidez que necesita el siguiente (sistema de 64 bits si)

ActivePython-2.7.2.5-win64-x64.msi
pywin32-217.win amd64 py2.7 .exe

ActivePython no tiene versiones anteriores de estos en su website por lo que tendrá que hacer un poco de google alrededor para encontrar un espejo de trabajo (hay muchos por ahí)

una vez que se han descargado el src de bitbucket puede necesitar editar spawn-php.py (para arreglar la pestaña spaci ng), ya que bit-bucket parecía arruinar las pestañas en el archivo impidiendo que se ejecutara.

All-in-all que salvó mi día para un pequeño sitio web de Windows ocupado usando nginx + fast-cgi.

Gracias amigo!

Cuestiones relacionadas