2010-05-08 3 views
6

EDIT: Mise à jour - défiler vers le bas
EDIT 2: Mise à jour - le problème est résolu PHP s'exécutant en tant qu'application FastCGI (php-cgi) - comment émettre des requêtes simultanées?


Quelques informations de fond:

J'écris mon propre serveur Web en Java et un couple Il ya quelques jours, j'ai demandé à SO comment exactement Apache s'interface avec PHP, donc je peux implémenter le support PHP. J'ai appris que FastCGI est la meilleure approche (puisque mod_php n'est pas une option). J'ai donc regardé la spécification du protocole FastCGI et j'ai réussi à écrire un wrapper FastCGI pour mon serveur. J'ai testé phpinfo() et cela fonctionne, en fait toutes les fonctions de PHP semblent fonctionner correctement (publication de données, sessions, date/heure, etc etc). Mon serveur web est capable de traiter simultanément des requêtes (ie user1 peut récupérer file1.html en même temps que user2 demandant un fichier_large_binary_file.zip), il le fait en engendrant un nouveau thread Java pour chaque requête utilisateur (se terminant à la fin ou la connexion de l'utilisateur avec le client est annulée).

Cependant, il ne peut pas traiter 2 (ou plus) requêtes FastCGI en même temps. Ce qu'il fait, il les met en file d'attente, donc lorsque la requête 1 est terminée immédiatement, il commence à traiter la requête 2. J'ai testé cela avec 2 pages PHP, l'une contient sleep (10) et l'autre phpinfo().

Comment pourrais-je traiter plusieurs demandes comme je sais que cela peut être fait (PHP sous IIS s'exécute en FastCGI et peut traiter plusieurs requêtes très bien).

Quelques infos:

Je suis codage sous Windows et mon fichier de commandes utilisé pour exécuter php-cgi.exe contient:

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

Mais il ne frayent pas 8 enfants, le service se termine simplement après 500 demandes.

I ont fait des recherches et de Wikipedia: (.-À-dire multiple des requêtes sur une seule connexion)

traitement de demandes multiples est réalisée simultanément soit par en utilisant une seule connexion avec multiplexage interne et/ou en utilisant plusieurs connexions

Maintenant clairement les connexions multiples ne fonctionne pas pour moi, comme à chaque fois un client reque sts quelque chose qui implique FastCGI, il crée un nouveau socket à l'application FastCGI, mais il ne fonctionne pas simultanément (il les met en file d'attente à la place).

Je sais que le multiplexage interne des requêtes FastCGI sous la même connexion est accompli en émettant chaque requête FastCGI unique avec un request ID différent. (voir également les 3 derniers paragraphes du titre «Le protocole de communication» dans this article).

Je n'ai pas testé cela, mais comment m'y prendre pour l'implémenter?Je suppose que j'ai besoin d'un thread Java FastCGI qui contient une carte quelconque et une fonction statique que je peux utiliser pour ajouter des requêtes. Ensuite, dans la fonction run() du Thread, il aurait une boucle while et pour chaque cycle il vérifierait si la Map contient de nouvelles requêtes, si c'est le cas, il leur attribuerait un ID de requête et les écrirait dans le flux FastCGI. Et puis attendez l'entrée etc etc, Comme vous pouvez le voir, cela devient trop compliqué.

Est-ce que quelqu'un connaît la bonne façon de faire cela? Ou des pensées du tout? Merci beaucoup.

Remarque, si nécessaire, je peux fournir le code pour mon wrapper FastCGI.


Mise à jour:

Fondamentalement, je nginx téléchargé et le configurer pour utiliser PHP comme une application FastCGI et trop souffert du même problème que mon serveur. Il ne pouvait pas gérer les requêtes PHP simultanées. Cela m'amène à croire que mon code est correct. Donc, quelque chose ne va pas avec PHP ou je ne le configure pas correctement. C'est peut-être parce que j'utilise Windows parce que certains utilisateurs de lighttpd affirment que Windows ne peut pas gérer correctement FastCGI (cela n'a pas beaucoup de sens). Je vais bientôt installer Linux et signaler tout progrès avec cela.

+0

Très bien, je suis juste resté sur ce problème pendant un jour, et difficile de comprendre ce qui se passe sur le sommeil() de PHP affectera d'autres processus, merci pour votre réponse et partager. – ykc

Répondre

6

Bon, j'ai réussi à trouver la cause du problème. Ce n'était pas mon code du tout. C'est PHP, il ne peut pas engendrer d'autres php-cgi sous Windows en mode FastCGI, sous Linux cela fonctionne parfaitement, j'ai simplement orienté mon serveur vers mon IP Linux et il n'y avait pas de problèmes avec les requêtes FCGI simultanées. Suce, mais je suppose que c'est comme ça ...

J'ai regardé plus loin dans le code source PHP après cela et j'ai trouvé que la section de code qui répond à PHP_FCGI_CHILDREN a été encapsulée par #ifndef WIN32 Donc les développeurs doivent Soyez conscient de la question

2

Salut cela vient un peu tard, j'ai écrit un géniteur pour php-cgi.exe sur Windows, pas parfait mais il pourrait être ce dont vous aviez besoin. Vérifiez-le au here.

+0

Oh très gentil, je vais jeter un oeil à ça! –

+0

homme halleluya, après 2 jours de googling extensif et en réalisant que php-cgi.exe peut servir 1 connexion simultanée je cherchais désespérément à développer localement sur apache et sur le serveur j'ai nginx, mais je voulais avoir la même configuration dans les deux environnements. donc votre solution a aidé. btw cela fonctionne seulement avec activepython, parce qu'il a win32processes, le python standard n'a pas cette lib – Skyzer

2

re: script python rogue php ...

Merci @nosam qui a vraiment aidé.
Pour ceux qui veulent le faire fonctionner rapidement, vous aurez besoin des éléments suivants (si le système 64 bits)

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

ActivePython n'a pas les anciennes versions de ces derniers sur leur www de sorte que vous aurez besoin de faire un peu de googler autour de trouver un miroir de travail (il y a beaucoup là-bas)

une fois que vous avez téléchargé le src de bitbucket vous devrez peut-être modifier spawn-php.py (pour réparer l'onglet spaci ng), car bit-bucket semblait gâcher les onglets du fichier, l'empêchant de fonctionner.

Tout-en-un qui a sauvé ma journée pour un petit site web Windows occupé en utilisant nginx + fast-cgi.

Merci mon pote!