8
votes

Compréhension mod_proxy et apache 2 pour écrire un serveur COMet

J'essaie actuellement de mettre en œuvre un simple serveur http pour une sorte de Comet -technique (interrogation longue XHR-requêtes). Comme JavaScript est très strict sur les demandes de crossomain, j'ai quelques questions:

  1. Comme j'ai compris tout travailleur Apache est bloqué tout en servant une demande, écrivez ainsi le "script" en tant que site Web habituel bloquerait l'Apache, lorsque tous les travailleurs ayant une demande de service. -> ne fonctionne pas!
  2. Je suis venu avec l'idée qui écrit un propre serveur HTTP simple uniquement pour servir ces longues demandes de vote. Ce serveur ne doit pas bloquer, chaque travailleur pouvait donc gérer de nombreuses demandes en même temps. Comme mon site contient également du contenu / d'images, etc. et que mon serveur n'a pas besoin de contenteur de serveur, je l'ai commencé sur un autre port puis 80. Le problème est que je ne peux pas interagir entre mon JavaScript livré par Mon Apache et mon serveur Comet fonctionnant sur un autre port, en raison de restrictions croisées. -> ne fonctionne pas!
  3. Puis j'ai eu l'idée d'utiliser mod_proxy pour mapper mon serveur sur un nouveau sous-domaine. Je ne pouvais vraiment pas comprendre comment mod_proxy fonctionne mais je pouvais imaginer que je sais avoir le même effet que sur ma première approche?

    Quel serait le meilleur moyen de créer ce type de combinaison de ce type de site Web classique et de ces demandes XHR de longue date? Dois-je mettre en œuvre la livraison de contenu sur mon serveur chez moi?


0 commentaires

5 Réponses :


3
votes

Je suis sûr que l'utilisation de mod_proxy bloquera un travailleur alors que la demande est en cours de traitement.

Si vous pouvez utiliser 2 IPS, il existe une solution assez facile. Disons que IP A est 1.1.1.1 et IP B est 2.2.2.2 et disons votre domaine est exemple.com.

Voici comment cela fonctionnera:

-configure Apache à écouter sur le port 80, mais uniquement sur IP A.

-Startez votre autre serveur sur le port 80, mais uniquement sur IP b.

-configure Les demandes XHR doivent être sur un sous-domaine de votre domaine, mais avec le même port. Donc, les restrictions croisées ne les empêchent pas. Donc, votre site est Exemple.com et les demandes XHR vont à xhr.example.com, par exemple.

-configurer votre DNS de sorte que Exemple.com se résout à IP A, et xhr.example.com se résout à IP b.

-Vous avez fait.

Cette solution fonctionnera si vous avez 2 serveurs et chacun a son IP, et cela fonctionnera également si vous avez un serveur avec 2 IPS.

Si vous ne pouvez pas utiliser 2 IPS, je peux avoir une autre solution, je vérifie s'il est applicable à votre cas.


2 commentaires

Je suis intéressé par l'idée avec une seule adresse IP.


Je ne pense pas que le modèle de sécurité du navigateur permet au code chargé de l'exemple.com d'envoyer des XHRS à xhr.example.com. Vous devez jouer à des jeux avec document.Domain et iframes, puis ce n'est pas portable. - fettig.net/weblog/2005/11/28/...



3
votes

C'est un problème difficile. Même si vous avez dépassé les problèmes de sécurité que vous rencontrez, vous finirez de disposer d'une connexion TCP ouverte pour chaque client en regardant actuellement une page Web. Vous ne pourrez pas créer de fil pour gérer chaque connexion et vous ne pourrez pas «sélectionner» sur toutes les connexions à partir d'un seul fil. Ayant fait cela auparavant, je peux vous dire que ce n'est pas facile. Vous voudrez peut-être examiner libefent , qui Memcached utilise à une extrémité similaire.

Jusqu'à un point, vous pouvez probablement vous éloigner avec de longues délais d'attente et permettre à Apache d'avoir un grand nombre de travailleurs, dont la plupart seront inactifs la plupart du temps. Choix minutieux et la configuration du module Travailleur Apache va étirer ceci à des milliers d'utilisateurs simultanés, je crois. À un moment donné, cependant, il ne sera plus intensifié.

Je ne sais pas ce que vous êtes infrastructure, mais nous avons des boîtes d'équilibrage de charge dans les racks de réseau appelés F5S. Celles-ci présentent un seul domaine externe, mais redirigent le trafic vers plusieurs serveurs internes en fonction de leurs temps de réponse, des cookies dans les en-têtes de la requête, etc. Ils peuvent être configurés pour envoyer des demandes pour un certain chemin dans le domaine virtuel à un serveur spécifique. Ainsi, vous pourriez avoir exemple.com/xhr/foo Demandes mappées sur un serveur spécifique pour gérer ces demandes de comète. Malheureusement, ce n'est pas une solution logicielle, mais une solution matérielle assez coûteuse.

Quoi qu'il en soit, vous aurez peut-être besoin d'une sorte de système d'équilibrage de charge (ou peut-être que vous en avez déjà un déjà), et peut-être peut-être être configuré pour gérer cette situation mieux que Apache Can.

J'ai eu une problématique il y a des années où je voulais que les clients utilisent un système client-serveur avec un protocole binaire propriétaire pour pouvoir accéder à nos serveurs sur le port 80 car ils ont continuellement des problèmes de pare-feu sur le port personnalisé sur le système personnalisé que le système utilisé. . Ce dont j'avais besoin était un proxy qui vivrait sur le port 80 et dirigerait le trafic vers Apache ou le serveur d'applications en fonction des premiers octets de ce qui est apparu du client. J'ai cherché une solution et j'ai trouvé rien qui ajusté. J'ai envisagé d'écrire un module Apache, un plugin pour délégué, etc., mais éventuellement roulés par un service de proxy de détection de contenu personnalisé. Je pense que c'est le pire des cas de ce que vous essayez de faire.


0 commentaires

0
votes

Pour répondre à la question spécifique sur mod-proxy: oui , vous pouvez configurer mod_proxy pour servir de contenu généré par un serveur (ou un service) non public (c'est-à-dire uniquement disponible. via une adresse interne ou localhost).

Je l'ai fait dans un environnement de production et cela fonctionne très bien. Apache transfère certaines demandes de Tomcat via des travailleurs AJP, et d'autres à un serveur d'applications SIG via Mod Proxy. Comme d'autres l'ont souligné, la sécurité croisée peut vous empêcher de travailler sur un sous-domaine, mais il n'y a aucune raison pour que vous ne puissiez pas demander des demandes de proxy à MyDomain.com/application


Parler de votre problème spécifique - je pense que vous êtes vraiment enlisé en regardant le problème comme "demandes de longue durée" - c'est-à-dire que lorsque vous effectuez une de ces demandes, tout le processus doit s'arrêter. Il semble que vous essayiez de résoudre un problème avec une architecture d'application via des modifications à l'architecture du système. En fait, ce que vous devez faire est de traiter ces demandes d'arrière-plan exactement en tant que telles; et multi-thread it:

  • Le client fait la demande au service à distance " Effectuer la tâche X avec les données A, B et C "
  • Votre service reçoit la demande: elle le transmet sur un planificateur qui émet un ticket unique / jeton unique pour la demande. Le service renvoie ensuite ce jeton au client " merci, votre tâche est dans une file d'attente exécutée sous jeton z " "
  • Le client se bloque ensuite sur ce jeton, montre une zone "Chargement / Please Wait", et met en place une minuterie que les incendies disent, pour des arguments, chaque seconde
  • Lorsque la minuterie incendie, le client fait une autre demande au service à distance " avez-vous les résultats de ma tâche, c'est un jeton z " "
  • Votre service de base peut ensuite vérifier auprès de votre planificateur et renvoyera probablement un document vide " non, pas encore fait " ou les résultats
  • Lorsque le client reçoit les résultats, il peut simplement effacer la minuterie et les afficher.

    Tant que vous êtes raisonnablement à l'aise avec le filetage (que vous devez être si vous avez indiqué que vous souhaitez écrire votre propre serveur HTTP, cela ne devrait pas être trop complexe - en haut de la partie à l'écoute HTTP:

    • Objet du planificateur - Objet Singleton, vraiment qui enveloppe une pile "premier dans, première sortie". Les nouvelles tâches vont à la fin de la pile, les travaux peuvent être tirés du début: assurez-vous simplement que le code pour émettre un travail est le fil de sécurité (moins vous obtenez deux œuvres tirant le même emploi de la pile).
    • Les threads de travailleur peuvent être assez simples - obtenir un accès au planificateur, demandez le prochain travail: S'il y en a un, effectuez-en une fois que le travail envoie les résultats, sinon il suffit de dormir pendant une période, recommencez.

      De cette façon, vous n'allez jamais bloquer Apache plus longtemps que nécessaire, car tout ce que vous faites, c'est des demandes de problèmes pour "faire x" ou "donner des résultats pour x". Vous voudrez probablement construire certaines caractéristiques de sécurité dans quelques points, telles que la manipulation des tâches qui échouent, et assurez-vous qu'il existe un délai de temps sur le côté du client afin qu'il n'attend pas indéfiniment.


0 commentaires

0
votes

Pour le numéro 2: Vous pouvez contourner des restrictions de crossomain à l'aide de JSONP.


0 commentaires

0
votes

deux trois Alternatives:

  1. Utilisez nginx . Cela signifie que vous exécutez 3 serveurs: Nginx, Apache et votre propre serveur.
  2. Exécutez votre serveur sur son propre port.
  3. Utilisez Apache mod_proxy_http (comme votre propre suggestion).

    J'ai confirmé que mod_proxy_http (Apache 2.2.16) fonctionne Proxy de la demande de comète (alimenté par Atmosphere 0.7.1) en cours d'exécution dans Glassfish 3.1.1.

    My Test App avec la source complète est ici: https://github.com/ceefour/jsfajaxpush


0 commentaires