Serveur HTTP capable de faire des requêtes par proxy

Pour des raisons de performance, j’ai dû réécrire une partie de notre infrastructure Web.

À cette fin, j’ai écrit la partie critique en tant qu’application Web en C ++. Cette application Web écoute sur un port donné, accepte exactement une connexion TCP à la fois et traite toutes les requêtes HTTP reçues sur la connexion en cours.

Vous pouvez le démarrer comme ça pour écouter sur le port 8080:

./webapp 8080 

Bien qu’il fonctionne parfaitement et beaucoup plus rapidement qu’avant, sa limitation est la nature unique de la connexion de l’application. Vous ne pouvez pas diffuser des pages HTML, Javascript et des images simultanément sur plusieurs connexions avec une seule instance de l’application.

Pour surmonter cette limitation, je souhaite exécuter un serveur HTTP frontal, qui écoute sur le port 80, et redirige les requêtes HTTP entrantes de manière uniforme sur plusieurs instances de mon application Web exécutée en arrière-plan. Ces instances pourraient être créées au démarrage comme ceci:

 ./webapp 10000 ./webapp 10001 ./webapp 10002 ./webapp 10003 ./webapp 10004 ./webapp 10005 ./webapp 10006 ./webapp 10007 ./webapp 10008 ./webapp 10009 

Le client doit être configuré pour établir une connexion HTTP permanente à chaque application Web au moment du démarrage , puis transférer les requêtes HTTP entrantes vers l’une des applications Web en cours d’exécution, en les répartissant de manière uniforme.

Le reverse-proxy doit également prendre en charge SSL du client à lui-même. Le soutien de SPDY serait un plus, mais ce n’est pas un must.

Ma question est la suivante: quels proxy inverses HTTP pourraient fonctionner en tant que frontend dans mon scénario? Si vous en connaissez plus d’un, quels sont les avantages et les inconvénients de chacun?

Quelle est votre motivation pour avoir un seul serveur de connexion? Cela semble être un choix terrible pour un serveur Web. Chaque navigateur client enverra généralement des dizaines de requêtes en parallèle lorsque votre site apparaît.

Si vous générez un processus par connexion TCP, vous finirez par avoir de mauvaises performances. En réalité, ce que vous recherchez ici est un serveur multithread au lieu d’une infrastructure multiprocessus (quel est l’intérêt d’avoir des processus différents?)

Cependant, il y a plusieurs chemins à parcourir:

  • Vous webapp votre application webapp chaque fois que vous recevez une demande si vous voulez vraiment avoir des processus séparés. Ce ne sera pas une bonne performance, mais c’est la question la plus proche de ma question initiale.

  • Vous restz avec votre application webapp thread webapp mais vous conservez une liste de sockets que vous écoutez, et vous les webapp à leur “socket de contact” auquel ils transmettent le trafic (notez que cela fonctionne dans les deux sens). Cependant, cela ne sera pas optimal en termes de performances, car vous pourriez être lié aux appels du kernel.

  • Vous générez un nouveau thread pour chaque requête, puis traitez cette requête uniquement dans ce thread, comme vous le faites avec votre architecture à thread unique.

Si j’étais vous, je me tournerais directement vers la solution 3, car c’est simplement le meilleur choix. Cela ne pose pas trop de problème, car il rest proche de votre approche à un seul thread (juste une paire de sockets) et il n’a pas le même impact sur les performances que sur les processus d’emballage.

Je ne pense pas que vous trouverez un serveur Web qui corresponde à vos besoins, car ce n’est pas un moyen standard de gérer de telles situations, et je doute que quiconque ait pris le temps de le développer 🙂

Modifier:

Ok, je comprends votre problème de votre édition.

Cependant, pour moi, le problème à résoudre est toujours le même: vous avez besoin d’un processus qui dissortingbue le trafic à vos processus. Je ne pense pas que vous trouverez un tel expéditeur prêt à l’emploi, et vous devrez donc l’implémenter en utilisant l’une des trois techniques que j’ai mentionnées.

Si vous y réfléchissez, vous essayez vraiment d’implémenter un côté d’un proxy et l’autre côté est le transfert vers votre webapp . Donc, vous devriez utiliser les techniques de proxy à mon humble avis.

On dirait que vous n’avez pas nécessairement besoin d’un proxy inverse, mais plutôt d’un équilibreur de charge. J’ai configuré HAProxy pour que chaque processus webapp compte comme un backend, puis effectue un équilibrage circulaire afin que chaque nouvelle connexion passe au processus suivant de la liste.

Nginx peut également faire ces choses, mais je ne suis pas sûr que cela soit accompagné d’un équilibrage de la charge ou d’un module supplémentaire. L’avantage de Nginx est qu’il peut mettre en cache des ressources statiques telles que des CSS et des images.

Nginx est une bonne option

Avantages:

  • Prend en charge la terminaison SSL
  • Prend en charge l’équilibrage de la charge hors de la boîte
  • Connexions Keepalive en amont
  • Prise en charge de SPDY (pas de pression sur le serveur). La dernière version ajoute le support http2 avec spdy supprimé.

Les inconvénients:

  • Vous devrez coder en dur les serveurs en amont dans votre configuration nginx comme ci-dessous. Il n’y a pas de moyen facile de lire les parameters du serveur en amont via les variables d’environnement si vous les mettez à jour dynamicment.

     http { upstream myapp1 { server localhost:10000; server localhost:10001; server localhost:10002; } server { listen 443 ssl spdy; location / { proxy_pass http://myapp1; } } }