Question Options du serveur Ruby on Rails [fermé]


Toute la question de la configuration d'un serveur de développement pour mon application Ruby on Rails me perturbe. Il y a WEBrick, Mongrel, Passenger, Apache, Nginx et j'en suis sûr, et je ne comprends pas vraiment les différents rôles qu'ils jouent.

J'ai commencé à utiliser WEBrick, et maintenant j'utilise Mongrel pour le développement. Ces serveurs sont-ils autonomes ou sont-ils installés devant Apache?

J'ai lu à propos de Passenger et je ne comprends pas vraiment ce que c'est, le site dit "rend le déploiement des applications web Ruby un jeu d'enfant", remplace-t-il Mongrel? Est-ce comme Capistrano, qui déploie également des applications web?

Ayant à l'esprit que je voudrais tester SSL, et je crois que ce n'est pas pris en charge par mongrel, quelle est la meilleure configuration du serveur de développement?

Merci


530
2017-11-06 13:37


origine


Réponses:


Le mot "déploiement" peut avoir deux significations selon le contexte. Vous confondez également les rôles d'Apache / Nginx avec les rôles des autres composants.

Note historique: Cet article a été écrit le 6 novembre 2010, lorsque l'écosystème du serveur d'applications Ruby était limité. J'ai mis à jour cet article le 15 mars 2013 avec toutes les dernières mises à jour de l'écosystème.

Avertissement: Je suis l'un des auteurs de Phusion Passenger, l'un des serveurs d'applications.

Apache vs Nginx

Ce sont deux serveurs Web. Ils peuvent servir des fichiers statiques mais, avec les bons modules, peuvent également servir des applications Web dynamiques, par exemple. ceux écrits en PHP. Apache est plus populaire et a plus de fonctionnalités, Nginx est plus petit et plus rapide et a moins de fonctionnalités.

Ni Apache ni Nginx ne peuvent utiliser les applications web Ruby prêtes à l'emploi. Pour ce faire, vous devez utiliser Apache / Nginx en combinaison avec une sorte d'add-on, décrite plus tard.

Apache et Nginx peuvent également agir comme des proxys inverses, ce qui signifie qu'ils peuvent prendre une requête HTTP entrante et la transmettre à un autre serveur, qui parle également HTTP. Lorsque ce serveur répond avec une réponse HTTP, Apache / Nginx transmettra la réponse au client; Vous apprendrez plus tard pourquoi cela est pertinent.

Mongrel et autres serveurs d'applications de production vs WEBrick

Mongrel est un "serveur d'application" Ruby: Concrètement, cela signifie que Mongrel est une application qui:

  1. Charge votre application Ruby dans son propre espace de processus.
  2. Configure un socket TCP, lui permettant de communiquer avec le monde extérieur (par exemple Internet). Mongrel écoute les requêtes HTTP sur ce socket et transmet les données de la requête à l'application web Ruby.
  3. L'application Web Ruby retourne ensuite un objet, qui décrit à quoi la réponse HTTP devrait ressembler, et Mongrel prend soin de la convertir en une réponse HTTP réelle (les octets réels) et la renvoie sur le socket.

Cependant Mongrel est assez daté, de nos jours il n'est plus entretenu. Les nouveaux serveurs d'applications alternatives sont:

  • Phusion Passenger
  • Licorne
  • Mince
  • Puma
  • Trinidad (JRuby seulement)
  • TorqueBox (JRuby uniquement)

Je vais les couvrir plus tard et décrire comment ils diffèrent les uns des autres et de Mongrel.

WEBrick fait la même chose que Mongrel, mais les différences sont:

  • WEBrick n'est pas fait pour la production, contrairement à tout ce que j'ai mentionné auparavant. WEBrick est entièrement écrit en Ruby. Mongrel (et la plupart des autres serveurs d'applications Ruby) fait partie de Ruby et de la partie C (Mostly Ruby), mais son analyseur HTTP est écrit en C pour les performances.
  • WEBrick est plus lent et moins robuste. Il a quelques fuites de mémoire connues et quelques problèmes connus d'analyse HTTP.
  • WEBrick est généralement utilisé uniquement comme serveur par défaut pendant le développement car WEBrick est inclus dans Ruby par défaut. Mongrel et d'autres serveurs d'applications doivent être installés séparément. Il n'est pas recommandé d'utiliser WEBrick dans des environnements de production, bien que, pour une raison quelconque, Heroku ait choisi WEBrick comme serveur par défaut. Ils utilisaient Thin avant, donc je ne sais pas pourquoi ils sont passés à WEBrick.

Le serveur d'applications et le monde

Tous les serveurs d'application Ruby actuels parlent le protocole HTTP, mais certains serveurs d'applications peuvent être directement exposés à Internet sur le port 80, alors que d'autres ne le peuvent pas.

  • Des serveurs d'applications directement accessibles sur Internet: Phusion Passenger, Rainbows
  • Les serveurs d'applications qui ne peuvent pas être directement exposés à Internet: Mongrel, Unicorn, Thin, Puma. Ces serveurs d'applications doivent être placés derrière un serveur Web proxy inverse comme Apache et Nginx.
  • Je ne sais pas assez sur Trinidad et TorqueBox, donc je les ai omis.

Pourquoi certains serveurs d'applications doivent-ils être mis derrière un proxy inverse?

  • Certains serveurs d'applications ne peuvent gérer qu'une seule requête simultanément, par processus. Si vous souhaitez gérer simultanément deux demandes, vous devez exécuter plusieurs instances de serveur d'applications, chacune desservant la même application Ruby. Cet ensemble de processus du serveur d'applications est appelé cluster de serveurs d'applications (d'où le nom Mongrel Cluster, Thin Cluster, etc.). Vous devez ensuite configurer Apache ou Nginx pour inverser le proxy de ce cluster. Apache / Nginx prendra soin de distribuer les requêtes entre les instances du cluster (Plus d'informations à ce sujet dans la section "Modèles de concordance d'E / S").
  • Le serveur Web peut mettre en tampon les demandes et les réponses, protégeant ainsi le serveur de l'application contre les «clients lents» - les clients HTTP qui n'envoient ou n'acceptent pas les données très rapidement. Vous ne voulez pas que votre serveur d'applications ne fasse rien en attendant que le client envoie la demande complète ou reçoive la réponse complète, car pendant ce temps, le serveur d'applications ne pourra peut-être rien faire d'autre. Apache et Nginx sont très doués pour faire beaucoup de choses en même temps parce qu'ils sont multithread ou evented.
  • La plupart des serveurs d'application peuvent servir des fichiers statiques, mais ne sont pas particulièrement bons. Apache et Nginx peuvent le faire plus rapidement.
  • Les utilisateurs configurent généralement Apache / Nginx pour servir directement les fichiers statiques, mais transmettent les demandes qui ne correspondent pas aux fichiers statiques au serveur de l'application. C'est une bonne pratique de sécurité. Apache et Nginx sont très matures et peuvent protéger le serveur de l'application des demandes (peut-être malicieusement) corrompues.

Pourquoi certains serveurs d'applications peuvent-ils être directement exposés à Internet?

  • Phusion Passenger est une bête très différente de tous les autres serveurs d'applications. Une de ses caractéristiques uniques est qu'il s'intègre dans le serveur Web.
  • L'auteur de Rainbows a déclaré publiquement qu'il est sûr de l'exposer directement à Internet. L'auteur est à peu près sûr qu'il n'y a pas de vulnérabilités dans l'analyseur HTTP (et similaire). Pourtant, l'auteur ne fournit aucune garantie et dit que l'utilisation est à ses risques et périls.

Comparaison des serveurs d'applications

Dans cette section, je comparerai la plupart des serveurs d'applications que j'ai mentionnés, mais pas Phusion Passenger. Phusion Passenger est une bête si différente que je lui ai donné une section dédiée. J'ai également omis Trinidad et TorqueBox parce que je ne les connais pas assez bien, mais elles ne sont pertinentes que si vous utilisez JRuby.

  • Bâtard était assez os nus. Comme mentionné précédemment, Mongrel est un multi-processus purement mono-thread, il n'est donc utile que dans un cluster. Il n'y a pas de surveillance du processus: si un processus du cluster tombe en panne (par exemple à cause d'un bogue dans l'application), il doit être redémarré manuellement. Les gens ont tendance à utiliser des outils de surveillance de processus externes tels que Monit et God.
  • Licorne est une fourchette de Mongrel. Il prend en charge la surveillance de processus limitée: si un processus se bloque, il est automatiquement redémarré par le processus maître. Il peut faire écouter tous les processus sur une seule socket partagée, au lieu d'une socket distincte pour chaque processus. Cela simplifie la configuration du proxy inverse. Comme Mongrel, c'est un multi-processus purement mono-thread.
  • Mince utilise le modèle d'E / S avec événement en utilisant la bibliothèque EventMachine. Autre que l'utilisation de l'analyseur HTTP Mongrel, il ne repose en aucune façon sur Mongrel. Son mode cluster n'a pas de surveillance de processus, vous devez donc surveiller les plantages, etc. Il n'y a pas de socket partagée de type Unicorn, donc chaque processus écoute sur son propre socket. En théorie, le modèle d'E / S de Thin permet une simultanéité élevée, mais dans la plupart des situations pratiques où Thin est utilisé, un processus Thin ne peut gérer qu'une seule requête simultanée, vous avez donc toujours besoin d'un cluster. Plus d'informations sur cette propriété particulière dans la section "Modèles de concordance d'E / S".
  • Puma a été également fourchue de Mongrel, mais contrairement à Unicorn, Puma est conçu pour être purement multi-threaded. Il n'y a donc actuellement aucun support de cluster intégré. Vous devez prendre soin de vous assurer que vous pouvez utiliser plusieurs cœurs (Pour en savoir plus, reportez-vous à la section "Modèles de concordance d'E / S").
  • Arcs en ciel prend en charge plusieurs modèles de concurrence en utilisant différentes bibliothèques.

Phusion Passenger

Phusion Passenger  fonctionne très différemment de tous les autres. Phusion Passenger s'intègre directement dans Apache ou Nginx, et peut donc être comparé à mod_php pour Apache. Tout comme mod_php permet à Apache de servir des applications PHP, presque par magie, Phusion Passenger permet à Apache (et aussi Nginx!) De servir les applications Ruby, presque par magie. L'objectif de Phusion Passenger est de faire en sorte que tout fonctionne de la manière la plus simple possible.

Au lieu de démarrer un processus ou un cluster pour votre application et de configurer Apache / Nginx pour qu'il traite les fichiers statiques et / ou les demandes de proxy inverse au processus / cluster avec Phusion Passenger, il vous suffit de:

  1. Vous modifiez le fichier de configuration du serveur Web et spécifiez l'emplacement du répertoire "public" de votre application Ruby.
  2. Il n'y a pas d'étape 2.

Toute la configuration est effectuée dans le fichier de configuration du serveur Web. Phusion Passenger automatise à peu près tout. Il n'est pas nécessaire de démarrer un cluster et de gérer les processus. Démarrer / arrêter des processus, les redémarrer quand ils tombent en panne, etc. - tous automatisés. Comparé aux autres serveurs d'application, Phusion Passenger a beaucoup moins de pièces mobiles. Cette facilité d'utilisation est l'une des principales raisons pour lesquelles les gens utilisent Phusion Passenger.

Contrairement à d'autres serveurs d'applications, Phusion Passenger est principalement écrit en C ++, ce qui le rend très rapide.

Il y a aussi un Variante d'entreprise de Phusion Passenger avec encore plus de fonctionnalités, telles que les redémarrages automatiques, le support multithread, la résistance aux erreurs de déploiement, etc.

Pour les raisons ci-dessus, Phusion Passenger est actuellement le serveur d'application le plus populaire de Ruby, alimentant plus de 150 000 sites Web, y compris les grands tels que le New York Times, Pixar, Airbnb, etc.

Phusion Passenger vs autres serveurs d'applications

Phusion Passenger fournit beaucoup plus de fonctionnalités et offre de nombreux avantages par rapport aux autres serveurs d'application, tels que:

  • Ajuster dynamiquement le nombre de processus basés sur le trafic. Nous exécutons une tonne d'applications Rails sur notre serveur à ressources limitées qui ne sont pas publiques, et que les membres de notre organisation n'utilisent que quelques fois par jour. Des choses comme Gitlab, Redmine, etc. Phusion Passenger peut faire déraper ces processus lorsqu'ils ne sont pas utilisés, et les faire tourner lorsqu'ils sont utilisés, ce qui permet de disposer de plus de ressources pour les applications plus importantes. Avec d'autres serveurs d'applications, tous vos processus sont activés en permanence.
  • Certains serveurs d'applications ne sont pas adaptés à certaines charges de travail, par définition. Par exemple, Unicorn est conçu pour les requêtes à exécution rapide uniquement. le site web Unicorn section "Juste pire dans certains cas".

Les charges de travail qui ne sont pas bonnes pour Unicorn sont:

  • Flux de travail en streaming (par exemple Rails 4 en direct ou Rails 4 en streaming).
  • Charges de travail dans lesquelles l'application effectue des appels d'API HTTP.

Le modèle d'E / S hybride Phusion Passenger Enterprise 4 ou plus tard, il est un excellent choix pour ces types de charges de travail.

  • Les autres serveurs d'applications nécessitent que l'utilisateur exécute au moins une instance par application. En revanche, Phusion Passenger prend en charge plusieurs applications dans une seule instance. Cela réduit considérablement les frais généraux d'administration.
  • Commutation automatique des utilisateurs, une fonction de sécurité pratique.
  • Phusion Passenger prend en charge de nombreux MRI Ruby, JRuby et Rubinius. Mongrel, Unicorn et Thin ne supportent que l'IRM. Puma prend également en charge tous les 3.
  • Phusion Passenger soutient réellement plus que Ruby! Il prend également en charge Python WSGI, il peut par exemple également exécuter des applications Django et Flask. En fait, Phusion Passenger est en train de devenir un serveur polyglotte. Node.js support sur la liste de tâches.
  • La collecte des ordures hors bande. Phusion Passenger peut exécuter le collecteur d'ordures Ruby en dehors du cycle normal de demande / réponse, ce qui peut réduire le temps de requête de centaines de millisecondes. Unicorn a également une fonctionnalité similaire, mais la version de Phusion Passenger est plus flexible car 1) il n'est pas limité à GC et peut être utilisé pour un travail arbitraire. 2) La version de Phusion Passenger fonctionne bien avec les applications multithread, contrairement à Unicorn.
  • Redémarrage automatique de roulement. Rolling redémarre sur Unicorn et d'autres serveurs nécessitent un travail de script. Phusion Passenger Enterprise automatise complètement cette manière pour vous.

Il y a plus de caractéristiques et d'avantages, mais la liste est vraiment longue. Vous devriez vous référer au manuel complet de Phusion Passenger (Version Apache, Version Nginx) ou le site de Phusion Passenger pour information.

Modèles de concordance d'E / S

  • Multi-processus mono-thread. C'est traditionnellement le modèle d'E / S le plus populaire pour les serveurs d'applications Ruby, en partie parce que le support du multithreading dans l'écosystème Ruby était très mauvais. Chaque processus peut gérer exactement 1 demande à la fois. La répartition de la charge du serveur Web entre les processus. Ce modèle est très robuste et le programmeur a peu de chance d'introduire des bogues de concurrence. Cependant, sa concurrence d'E / S est extrêmement limitée (limitée par le nombre de processus). Ce modèle est très approprié pour des charges de travail rapides et à court terme. Il est très inadapté pour des charges de travail d'E / S de blocage lentes et de longue durée, par ex. les charges de travail impliquant l'appel d'API HTTP.
  • Purement multi-threadé. De nos jours, l'écosystème Ruby a un excellent support multithread, donc ce modèle d'E / S est devenu très viable. Le multithreading permet une simultanéité élevée des E / S, ce qui le rend approprié à la fois pour les charges de travail d'E / S bloquantes de courte durée et de longue durée. Le programmeur est plus susceptible d'introduire des bogues concurrentiels, mais heureusement, la plupart des frameworks web sont conçus de telle façon que cela soit encore très improbable. Une chose à noter cependant est que l'interpréteur MRI Ruby ne peut pas tirer parti de plusieurs cœurs de CPU, même lorsqu'il y a plusieurs threads, en raison de l'utilisation de la Global Interpreter Lock (GIL). Vous pouvez contourner ce problème en utilisant plusieurs processus multithread, car chaque processus peut tirer parti d'un cœur de processeur. JRuby et Rubinius n'ont pas de GIL, ce qui leur permet de tirer pleinement parti de plusieurs cœurs en un seul processus.
  • Multi-processus hybride multithread. Principalement mis en œuvre par Phusion Passenger Enterprise 4 et versions ultérieures. Vous pouvez facilement basculer entre des processus multithread monoprocessus, purement multithread, ou peut-être même plusieurs, chacun avec plusieurs threads. Ce modèle donne le meilleur des deux mondes.
  • Evented. Ce modèle est complètement différent du modèle mentionné précédemment. Il permet une concurrence d'E / S très élevée et est donc excellent pour les charges de travail d'E / S de blocage de longue durée. Pour l'utiliser, un support explicite de l'application et du framework est requis. Cependant, tous les frameworks majeurs comme Rails et Sinatra ne supportent pas le code evented. C'est pourquoi, en pratique, un processus Thin ne peut toujours pas gérer plus d'une requête à la fois, ce qui fait qu'il se comporte de la même manière que le modèle multi-processus mono-thread. Il existe des cadres spécialisés qui peuvent tirer parti des E / S événementielles, telles que Cramp.

Un article a récemment été posté sur le blog de Phusion pour optimiser le nombre de processus et de threads en fonction de votre charge de travail. Voir Réglage des paramètres de concurrence de Tuning Phusion Passenger.

Capistrano

Capistrano est quelque chose de complètement différent. Dans toutes les sections précédentes, le terme «déploiement» fait référence au démarrage de votre application Ruby dans un serveur d'applications, afin qu'elle devienne accessible aux visiteurs, mais avant cela, vous devez généralement effectuer un travail de préparation, tel que:

  • Téléchargement du code et des fichiers de l'application Ruby sur le serveur.
  • Installation de bibliothèques dont votre application dépend.
  • Configuration ou migration de la base de données
  • Démarrage et arrêt de tous les démons sur lesquels votre application peut s'appuyer, tels que les travailleurs Sidekiq / Resque ou autres.
  • Tout ce qui doit être fait lors de la configuration de votre application.

Dans le contexte de Capistrano, "déploiement" se réfère à faire tout ce travail de préparation. Capistrano n'est pas un serveur d'application. Au lieu de cela, c'est un outil pour automatiser tout ce travail de préparation. Vous dites à Capistrano où se trouve votre serveur et quelles commandes doivent être exécutées chaque fois que vous déployez une nouvelle version de votre application, et Capistrano prendra soin de télécharger l'application Rails sur le serveur pour vous et exécuter les commandes que vous avez spécifiées.

Capistrano est toujours utilisé en combinaison avec un serveur d'application. Il ne remplace pas les serveurs d'applications. Vice-versa, les serveurs d'applications ne remplacent pas Capistrano, ils peuvent être utilisés en combinaison avec Capistrano.

Bien sûr, vous ne le faites pas avoir utiliser Capistrano. Si vous préférez télécharger votre application Ruby avec FTP et exécuter manuellement les mêmes étapes de commandes à chaque fois, vous pouvez le faire. D'autres personnes en ont eu assez, alors ils automatisent ces étapes à Capistrano.


1204