Options du serveur Ruby on Rails [fermé]

578

Toute la question de la mise en place d'un serveur de développement pour mon application Ruby on Rails m'embrouille. Il y a WEBrick, Mongrel, Passenger, Apache, Nginx et bien d'autres, je 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 se trouvent-ils devant Apache?

J'ai lu sur Passenger et je ne comprends pas vraiment ce que c'est, le site dit "facilite le déploiement des applications Web Ruby", remplace-t-il Mongrel? Est-ce comme Capistrano, qui déploie également des applications Web?

En gardant à 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 de serveur de développement?

Merci

pingu
la source
2
Avez-vous regardé le screencast Phusion Passenger? Il décrit à peu près en 5 minutes tout ce qui est nécessaire pour mettre votre application Rails en ligne.
Hongli
27
Pour une question non constructive, cela a certainement suscité beaucoup de votes positifs, tout comme la réponse.
Teemu Leisti
32
Je sais que cette question enfreint les règles de SO, mais je me demande si beaucoup d'utilisateurs trouvent cette question utile, peut-être qu'il est temps de modifier certaines règles?
Hardik

Réponses:

1264

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

Remarque historique: Cet article a été écrit à l'origine 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 celles écrites 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 servir les applications Web Ruby prêtes à l'emploi, pour ce faire, vous devez utiliser Apache / Nginx en combinaison avec une sorte de module complémentaire, décrit plus loin.

Apache et Nginx peuvent également agir en tant que proxys inversés, 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 retransmet la réponse au client; Vous découvrirez plus tard pourquoi cela est pertinent.

Mongrel et autres serveurs d'applications de production vs WEBrick

Mongrel est un "serveur d'applications" 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 requête à l'application Web Ruby.
  3. L'application Web Ruby renvoie ensuite un objet, qui décrit à quoi devrait ressembler la réponse HTTP, et Mongrel se charge de le convertir en une réponse HTTP réelle (les octets réels) et le renvoie sur le socket.

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

  • Passager Phusion
  • Licorne
  • Mince
  • Puma
  • Trinidad (JRuby uniquement)
  • TorqueBox (JRuby uniquement)

Je les couvrirai plus tard et décrirai en quoi ils diffèrent les uns des autres et de Mongrel.

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

  • WEBrick n'est pas apte à 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 Ruby et partie C (Mostly Ruby), mais son analyseur HTTP est écrit en C pour des performances.
  • WEBrick est plus lent et moins robuste. Il présente des fuites de mémoire connues et des problèmes d'analyse HTTP connus.
  • WEBrick n'est généralement utilisé que comme serveur par défaut pendant le développement car WEBrick est inclus dans Ruby par défaut. Mongrel et les 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 auparavant, donc je ne sais pas pourquoi ils sont passés à WEBrick.

Le serveur d'applications et le monde

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

  • Serveurs d'applications pouvant être directement exposés à Internet: Phusion Passenger, Rainbows
  • 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 connais pas assez Trinidad et TorqueBox, donc je les ai omis.

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

  • Certains serveurs d'applications ne peuvent gérer qu'une seule demande simultanément, par processus. Si vous souhaitez gérer 2 demandes simultanément, vous devez exécuter plusieurs instances de serveur d'applications, chacune desservant la même application Ruby. Cet ensemble de processus de serveur d'applications est appelé un cluster de serveurs d'applications (d'où le nom de cluster Mongrel, cluster léger, etc.). Vous devez ensuite configurer Apache ou Nginx pour inverser le proxy vers ce cluster. Apache / Nginx se chargera de répartir les requêtes entre les instances du cluster (Plus d'informations à ce sujet dans la section "Modèles de concurrence d'E / S").
  • Le serveur Web peut mettre en mémoire tampon les demandes et les réponses, protégeant le serveur d'applications des "clients lents" - 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 qu'il reçoive la réponse complète, car pendant ce temps, le serveur d'applications ne pourra rien faire d'autre. Apache et Nginx sont très bons pour faire beaucoup de choses en même temps car ils sont soit multithreadés soit événementiels.
  • La plupart des serveurs d'applications peuvent servir des fichiers statiques, mais ne sont pas particulièrement bons dans ce domaine. Apache et Nginx peuvent le faire plus rapidement.
  • Les gens 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 d'application, c'est une bonne pratique de sécurité. Apache et Nginx sont très matures et peuvent protéger le serveur d'applications contre (peut-être par malveillance) les demandes 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. L'une de ses caractéristiques uniques est qu'il s'intègre au serveur Web.
  • L'auteur Rainbows a déclaré publiquement qu'il est sûr de l'exposer directement à Internet. L'auteur est assez sûr qu'il n'y a aucune vulnérabilité dans l'analyseur HTTP (et similaire). Néanmoins, l'auteur n'offre aucune garantie et affirme que l'utilisation est à ses propres risques.

Comparaison des serveurs d'applications

Dans cette section, je vais comparer la plupart des serveurs d'applications que j'ai mentionnés, mais pas Phusion Passenger. Phusion Passenger est une bête tellement différente des autres 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 ils ne sont pertinents de toute façon que si vous utilisez JRuby.

  • Le bâtard était des os assez nus. Comme mentionné précédemment, Mongrel est un processus multi-processus purement monothread, il n'est donc utile que dans un cluster. Il n'y a pas de surveillance des processus: si un processus du cluster se bloque (par exemple à cause d'un bogue dans l'application), il doit être redémarré manuellement. Les gens ont tendance à utiliser des outils externes de surveillance des processus tels que Monit et God.
  • La licorne est une fourchette de bâtard. Il prend en charge la surveillance limitée des processus: si un processus plante, il est automatiquement redémarré par le processus maître. Il peut faire écouter tous les processus sur un seul socket partagé, au lieu d'un socket séparé pour chaque processus. Cela simplifie la configuration du proxy inverse. Comme Mongrel, il s'agit d'un multi-processus purement monothread.
  • Thin utilise le modèle d'E / S avec événement en utilisant la bibliothèque EventMachine. À part l'utilisation de l'analyseur HTTP Mongrel, il n'est en aucun cas basé 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é de type Licorne, donc chaque processus écoute sur son propre socket. En théorie, le modèle d'E / S de Thin autorise une concurrence élevée, mais dans la plupart des situations pratiques pour lesquelles Thin est utilisé, un processus Thin ne peut gérer qu'une seule demande 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 concurrence d'E / S".
  • Puma était également issu de Mongrel, mais contrairement à Unicorn, Puma est conçu pour être purement multi-thread. Il n'y a donc actuellement aucun support de cluster intégré. Vous devez prendre des précautions particulières pour vous assurer que vous pouvez utiliser plusieurs cœurs (pour en savoir plus, consultez la section «Modèles de concurrence d'E / S»).
  • Rainbows prend en charge plusieurs modèles de concurrence grâce à l'utilisation de différentes bibliothèques.

Passager Phusion

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 comme par magie, Phusion Passenger permet à Apache (et aussi Nginx!) De servir des applications Ruby, presque comme par magie. L'objectif de Phusion Passenger est de tout faire fonctionner avec le moins de tracas possible.

Au lieu de démarrer un processus ou un cluster pour votre application et de configurer Apache / Nginx pour servir des fichiers statiques et / ou inverser les demandes de proxy au processus / cluster avec Phusion Passenger, vous devez seulement:

  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émarrage / arrêt des processus, redémarrage en cas de panne, etc. - le tout automatisé. Comparé à d'autres serveurs d'applications, 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 existe également une variante Enterprise de Phusion Passenger avec encore plus de fonctionnalités, telles que les redémarrages automatiques en continu, la prise en charge du multithreading, la résistance aux erreurs de déploiement, etc.

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

Phusion Passenger vs autres serveurs d'applications

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

  • Ajuster dynamiquement le nombre de processus en fonction du trafic. Nous exécutons une tonne d'applications Rails sur notre serveur limité en ressources qui ne sont pas accessibles au public et que les membres de notre organisation n'utilisent au maximum que quelques fois par jour. Des choses comme Gitlab, Redmine, etc. Phusion Passenger peut ralentir ces processus lorsqu'ils ne sont pas utilisés, et les faire tourner lorsqu'ils sont utilisés, permettant à plus de ressources d'être disponibles pour des 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 conception. Par exemple, Unicorn est conçu uniquement pour les demandes à exécution rapide: voir la section du site Web de Unicorn "Pire dans certains cas".

Les charges de travail auxquelles Unicorn n'est pas bon sont:

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

Le modèle d'E / S hybride de Phusion Passenger Enterprise 4 ou version ultérieure en fait un excellent choix pour ce type de charges de travail.

  • Pour les autres serveurs d'applications, l'utilisateur doit exécuter 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 d'administration.
  • Changement automatique d'utilisateur, une fonction de sécurité pratique.
  • Phusion Passenger prend en charge de nombreux IRM Ruby, JRuby et Rubinius. Mongrel, Unicorn et Thin ne prennent en charge que l'IRM. Puma prend également en charge les 3.
  • Phusion Passenger prend en charge 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 passe de devenir un serveur polyglotte. Prise en charge de Node.js sur la liste des tâches.
  • Collecte des ordures hors bande. Phusion Passenger peut exécuter le garbage collector Ruby en dehors du cycle normal de demande / réponse, réduisant potentiellement les délais de demande de centaines de millisecondes. Unicorn a également une fonctionnalité similaire, mais la version de Phusion Passenger est plus flexible car 1) elle n'est pas limitée au GC et peut être utilisée pour un travail arbitraire. 2) La version de Phusion Passenger fonctionne bien avec les applications multithread, contrairement à celle de Unicorn.
  • Redémarrage automatique du roulement. Le redémarrage en continu sur Unicorn et d'autres serveurs nécessite un certain travail de script. Phusion Passenger Enterprise automatise complètement cette façon pour vous.

Il y a plus de fonctionnalités et d'avantages, mais la liste est vraiment longue. Vous devez vous référer au manuel de passagers de Phusion complète ( Apache version , la version Nginx ) ou le site Web du passager Phusion pour information.

Modèles de concurrence d'E / S

  • Multi-processus à filetage unique. Il s'agit traditionnellement du modèle d'E / S le plus populaire pour les serveurs d'applications Ruby, en partie parce que la prise en charge du multithreading dans l'écosystème Ruby était très mauvaise. Chaque processus peut traiter exactement 1 demande à la fois. Le serveur Web équilibre la charge entre les processus. Ce modèle est très robuste et il y a peu de chance pour le programmeur d'introduire des bogues de concurrence. Cependant, sa simultanéité d'E / S est extrêmement limitée (limitée par le nombre de processus). Ce modèle est très adapté aux charges de travail rapides et de courte durée. Il est très inapproprié pour les charges de travail d'E / S de blocage lentes et de longue durée, par exemple les charges de travail impliquant l'appel d'API HTTP.
  • Purement multi-thread. De nos jours, l'écosystème Ruby a un excellent support multithreading, donc ce modèle d'E / S est devenu très viable. Le multithreading permet une concurrence d'E / S élevée, ce qui le rend approprié pour les charges de travail d'E / S bloquantes à court terme et à long terme. Le programmeur est plus susceptible d'introduire des bogues de concurrence, mais heureusement, la plupart des cadres Web sont conçus de telle manière que cela est encore très peu probable. Cependant, une chose à noter est que l'interpréteur MRI Ruby ne peut pas exploiter plusieurs cœurs de processeur même lorsqu'il existe plusieurs threads, en raison de l'utilisation du verrouillage d'interprète global (GIL). Vous pouvez contourner ce problème en utilisant plusieurs processus multithreads, car chaque processus peut tirer parti d'un cœur de processeur. JRuby et Rubinius n'ont pas de GIL, ils peuvent donc exploiter pleinement plusieurs cœurs en un seul processus.
  • Multi-processus hybride multi-thread. Principalement implémenté par Phusion Passenger Enterprise 4 et versions ultérieures. Vous pouvez facilement basculer entre plusieurs processus à un seul thread, purement multithread ou peut-être même plusieurs processus avec chacun 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 principaux frameworks comme Rails et Sinatra ne prennent pas en charge le code événementiel. C'est pourquoi, dans la pratique, un processus Thin ne peut toujours pas gérer plus d'une demande à la fois, ce qui le fait se comporter efficacement de la même manière que le modèle multi-processus à thread unique. Il existe des cadres spécialisés qui peuvent tirer parti des E / S événementielles, comme Cramp.

Un article a récemment été publié sur le blog Phusion sur l'optimisation optimale du nombre de processus et de threads en fonction de votre charge de travail. Voir Réglage des paramètres de concurrence de Phusion Passenger .

Capistrano

Capistrano est quelque chose de complètement différent. Dans toutes les sections précédentes, "déploiement" fait référence au fait de démarrer votre application Ruby sur un serveur d'applications, afin qu'elle devienne accessible aux visiteurs, mais avant que cela ne se produise, il faut généralement effectuer un travail de préparation, tel que:

  • Téléchargement du code et des fichiers de l'application Ruby sur la machine serveur.
  • Installation des 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 autre.
  • Toutes autres tâches à effectuer lors de la configuration de votre application.

Dans le contexte de Capistrano, le «déploiement» fait référence à tout ce travail de préparation. Capistrano n'est pas un serveur d'applications. 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 se chargera de télécharger l'application Rails sur le serveur pour vous et d'exécuter les commandes que vous avez spécifiées.

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

Bien sûr, vous n'avez pas besoin d'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 elles automatisent ces étapes à Capistrano.

Hongli
la source
74
Vous devriez publier cela quelque part. Tout est facile maintenant, mais lorsque j'ai commencé avec les rails, il était difficile d'obtenir des informations utiles.
spegoraro
9
Excellent post! Ça m'a beaucoup éclairé aussi. Vous devriez ajouter d'autres éléments comme bundler et rvm et en faire un article de blog percutant! :)
Damien Roche
37
Cela doit être dans les guides Rails.
Dorian
4
"Personne n'utilise WEBrick dans les environnements de production." Ce n'est pas vrai du tout. Le serveur d'applications par défaut lors de la transmission d'applications ruby ​​à Heroku est Webrick.
John Downey
37
@Hongli Ce message est très favorable à Phusion Passenger. Peut-être serait-il judicieux d'ajouter votre affiliation au projet (CTO, phusion.nl/about ) dans un souci d'objectivité?
Bert Goethals