Opciones de Ruby on Rails Server [cerrado]

578

Toda la cuestión de configurar un servidor de desarrollo para mi aplicación Ruby on Rails me confunde. Estoy seguro de que hay WEBrick, Mongrel, Passenger, Apache, Nginx y muchos más, y realmente no entiendo los diferentes roles que desempeñan.

Comencé a usar WEBrick, y ahora uso Mongrel para el desarrollo. ¿Son estos servidores independientes o se sientan frente a Apache?

He leído sobre Passenger y realmente no entiendo lo que es, el sitio dice "hace que la implementación de aplicaciones web de Ruby sea muy fácil", ¿reemplaza a Mongrel? ¿Es como Capistrano, que también implementa aplicaciones web?

Teniendo en cuenta que me gustaría probar SSL, y creo que no es compatible con mongrel, ¿cuál es la mejor configuración del servidor de desarrollo?

Gracias

pingu
fuente
2
¿Has visto el screencast de Phusion Passenger? Describe más o menos en 5 minutos todo lo que se necesita para poner su aplicación Rails en línea.
Hongli
27
Para una pregunta poco constructiva, esto seguramente ha recibido muchos votos positivos, y también la respuesta.
Teemu Leisti
32
Sé que esta pregunta rompe las reglas de SO, pero me pregunto si muchos usuarios encuentran útil esta pregunta, ¿tal vez es hora de modificar algunas reglas?
Hardik

Respuestas:

1264

La palabra "despliegue" puede tener dos significados según el contexto. También está confundiendo los roles de Apache / Nginx con los roles de otros componentes.

Nota histórica: Este artículo se escribió originalmente el 6 de noviembre de 2010, cuando el ecosistema del servidor de aplicaciones Ruby era limitado. He actualizado este artículo el 15 de marzo de 2013 con todas las últimas actualizaciones del ecosistema.

Descargo de responsabilidad : soy uno de los autores de Phusion Passenger, uno de los servidores de aplicaciones.

Apache vs Nginx

Ambos son servidores web. Pueden servir archivos estáticos pero, con los módulos correctos, también pueden servir aplicaciones web dinámicas, por ejemplo, aquellas escritas en PHP. Apache es más popular y tiene más funciones, Nginx es más pequeño y más rápido y tiene menos funciones.

Ni Apache ni Nginx pueden servir aplicaciones web de Ruby listas para usar, para ello debe usar Apache / Nginx en combinación con algún tipo de complemento, que se describe más adelante.

Apache y Nginx también pueden actuar como servidores proxy inversos, lo que significa que pueden tomar una solicitud HTTP entrante y reenviarla a otro servidor, que también habla HTTP. Cuando ese servidor responde con una respuesta HTTP, Apache / Nginx reenviará la respuesta al cliente; Más adelante aprenderá por qué esto es relevante.

Servidores de aplicaciones de producción mestizos y otros vs WEBrick

Mongrel es un "servidor de aplicaciones" de Ruby: en términos concretos, esto significa que Mongrel es una aplicación que:

  1. Carga su aplicación Ruby dentro de su propio espacio de proceso.
  2. Configura un socket TCP, lo que le permite comunicarse con el mundo exterior (por ejemplo, Internet). Mongrel escucha las solicitudes HTTP en este socket y pasa los datos de la solicitud a la aplicación web Ruby.
  3. La aplicación web Ruby luego devuelve un objeto, que describe cómo debería ser la respuesta HTTP, y Mongrel se encarga de convertirla en una respuesta HTTP real (los bytes reales) y la envía de vuelta a través del socket.

Sin embargo, Mongrel está bastante anticuado, hoy en día ya no se mantiene. Los servidores de aplicaciones alternativos más nuevos son:

  • Phusion Passenger
  • Unicornio
  • Delgado
  • Puma
  • Trinidad (solo JRuby)
  • TorqueBox (solo JRuby)

Los cubriré más adelante y describiré en qué se diferencian entre sí y de Mongrel.

WEBrick hace lo mismo que Mongrel, pero las diferencias son:

  • WEBrick no es apto para la producción, a diferencia de todo lo que mencioné antes. WEBrick está escrito completamente en Ruby. Mongrel (y la mayoría de los otros servidores de aplicaciones de Ruby) es parte Ruby y parte C (principalmente Ruby), pero su analizador HTTP está escrito en C para el rendimiento.
  • WEBrick es más lento y menos robusto. Tiene algunas pérdidas de memoria conocidas y algunos problemas de análisis HTTP conocidos.
  • WEBrick generalmente solo se usa como servidor predeterminado durante el desarrollo porque WEBrick se incluye en Ruby de forma predeterminada. Mongrel y otros servidores de aplicaciones deben instalarse por separado. No se recomienda usar WEBrick en entornos de producción, aunque por alguna razón Heroku eligió WEBrick como su servidor predeterminado. Antes usaban Thin, así que no tengo idea de por qué se cambiaron a WEBrick.

El servidor de aplicaciones y el mundo.

Todos los servidores de aplicaciones Ruby actuales hablan HTTP, sin embargo, algunos servidores de aplicaciones pueden estar expuestos directamente a Internet en el puerto 80, mientras que otros no.

  • Servidores de aplicaciones que pueden estar expuestos directamente a Internet: Phusion Passenger, Rainbows
  • Servidores de aplicaciones que pueden no estar directamente expuestos a Internet: Mongrel, Unicorn, Thin, Puma. Estos servidores de aplicaciones deben colocarse detrás de un servidor web proxy inverso como Apache y Nginx.
  • No sé lo suficiente sobre Trinidad y TorqueBox, así que los he omitido.

¿Por qué algunos servidores de aplicaciones deben colocarse detrás de un proxy inverso?

  • Algunos servidores de aplicaciones solo pueden manejar 1 solicitud al mismo tiempo, por proceso. Si desea manejar 2 solicitudes al mismo tiempo, debe ejecutar varias instancias del servidor de aplicaciones, cada una de las cuales sirve la misma aplicación Ruby. Este conjunto de procesos del servidor de aplicaciones se denomina clúster de servidores de aplicaciones (de ahí el nombre de Mongrel Cluster, Thin Cluster, etc.). Luego debe configurar Apache o Nginx para invertir el proxy en este clúster. Apache / Nginx se encargará de distribuir las solicitudes entre las instancias en el clúster (más sobre esto en la sección "Modelos de concurrencia de E / S").
  • El servidor web puede amortiguar las solicitudes y respuestas, protegiendo el servidor de aplicaciones de "clientes lentos": clientes HTTP que no envían o aceptan datos muy rápidamente. No desea que su servidor de aplicaciones no haga nada mientras espera que el cliente envíe la solicitud completa o reciba la respuesta completa, ya que durante ese tiempo es posible que el servidor de aplicaciones no pueda hacer nada más. Apache y Nginx son muy buenos para hacer muchas cosas al mismo tiempo porque son multiproceso o tienen un diseño especial.
  • La mayoría de los servidores de aplicaciones pueden servir archivos estáticos, pero no son particularmente buenos en eso. Apache y Nginx pueden hacerlo más rápido.
  • Las personas generalmente configuran Apache / Nginx para servir archivos estáticos directamente, pero reenvían las solicitudes que no se corresponden con los archivos estáticos al servidor de aplicaciones, es una buena práctica de seguridad. Apache y Nginx son muy maduros y pueden proteger el servidor de aplicaciones de solicitudes corruptas (quizás maliciosas).

¿Por qué algunos servidores de aplicaciones pueden estar directamente expuestos a Internet?

  • Phusion Passenger es una bestia muy diferente de todos los demás servidores de aplicaciones. Una de sus características únicas es que se integra en el servidor web.
  • El autor de Rainbows declaró públicamente que es seguro exponerlo directamente a Internet. El autor está bastante seguro de que no hay vulnerabilidades en el analizador HTTP (y similares). Aún así, el autor no ofrece garantía y dice que el uso es bajo su propio riesgo.

Servidores de aplicaciones comparados

En esta sección compararé la mayoría de los servidores de aplicaciones que he mencionado, pero no Phusion Passenger. Phusion Passenger es una bestia tan diferente del resto que le he dado una sección dedicada. También he omitido Trinidad y TorqueBox porque no los conozco lo suficientemente bien, pero de todos modos solo son relevantes si usas JRuby.

  • El mestizo estaba bastante desnudo. Como se mencionó anteriormente, Mongrel es un multiproceso de un solo subproceso, por lo que solo es útil en un clúster. No hay monitoreo del proceso: si un proceso en el clúster falla (por ejemplo, debido a un error en la aplicación), entonces debe reiniciarse manualmente. Las personas tienden a usar herramientas externas de monitoreo de procesos como Monit y God.
  • Unicornio es un tenedor de mestizo. Es compatible con la supervisión limitada del proceso: si un proceso falla, el proceso maestro lo reinicia automáticamente. Puede hacer que todos los procesos escuchen en un único socket compartido, en lugar de un socket separado para cada proceso. Esto simplifica la configuración del proxy inverso. Al igual que Mongrel, es un multiproceso de un solo subproceso.
  • Thin utiliza el modelo de E / S creado mediante la biblioteca EventMachine. Aparte de usar el analizador HTTP Mongrel, no se basa en Mongrel de ninguna manera. Su modo de clúster no tiene monitoreo de proceso, por lo que debe monitorear fallas, etc. No hay un socket compartido similar a Unicorn, por lo que cada proceso escucha en su propio socket. En teoría, el modelo de E / S de Thin permite una alta concurrencia, pero en la mayoría de las situaciones prácticas para las que se usa Thin, un proceso Thin solo puede manejar 1 solicitud concurrente, por lo que aún necesita un clúster. Más información sobre esta propiedad peculiar en la sección "Modelos de concurrencia de E / S".
  • Puma también fue bifurcado de Mongrel, pero a diferencia de Unicornio, Puma está diseñado para ser puramente multiproceso. Por lo tanto, actualmente no hay soporte de clúster integrado. Debe tener especial cuidado para asegurarse de poder utilizar múltiples núcleos (Más información sobre esto en la sección "Modelos de concurrencia de E / S").
  • Rainbows admite múltiples modelos de concurrencia mediante el uso de diferentes bibliotecas.

Phusion Passenger

Phusion Passenger funciona de manera muy diferente a todos los demás. Phusion Passenger se integra directamente en Apache o Nginx, por lo que se puede comparar con mod_php para Apache. Al igual que mod_php permite que Apache sirva aplicaciones PHP, casi mágicamente, Phusion Passenger permite que Apache (¡y también Nginx!) Sirva aplicaciones Ruby, casi mágicamente. El objetivo de Phusion Passenger es hacer que todo funcione (tm) con la menor molestia posible.

En lugar de iniciar un proceso o clúster para su aplicación, y configurar Apache / Nginx para servir archivos estáticos y / o solicitudes de proxy inverso al proceso / clúster con Phusion Passenger solo necesita:

  1. Edita el archivo de configuración del servidor web y especifica la ubicación del directorio 'público' de su aplicación Ruby.
  2. No hay paso 2.

Toda la configuración se realiza dentro del archivo de configuración del servidor web. Phusion Passenger automatiza casi todo. No es necesario iniciar un clúster y administrar procesos. Iniciar / detener procesos, reiniciarlos cuando se bloquean, etc., todo automatizado. En comparación con otros servidores de aplicaciones, Phusion Passenger tiene muchas menos piezas móviles. Esta facilidad de uso es una de las principales razones por las cuales las personas usan Phusion Passenger.

Además, a diferencia de otros servidores de aplicaciones, Phusion Passenger está escrito principalmente en C ++, lo que lo hace muy rápido.

También hay una variante Enterprise de Phusion Passenger con aún más características, como reinicios automáticos, compatibilidad con subprocesos múltiples, resistencia a errores de implementación, etc.

Por las razones anteriores, Phusion Passenger es actualmente el servidor de aplicaciones Ruby más popular, con más de 150,000 sitios web, incluidos los grandes como New York Times, Pixar, Airbnb, etc.

Phusion Passenger frente a otros servidores de aplicaciones

Phusion Passenger ofrece muchas más funciones y muchas ventajas sobre otros servidores de aplicaciones, como:

  • Ajuste dinámico de la cantidad de procesos en función del tráfico. Ejecutamos una tonelada de aplicaciones Rails en nuestro servidor de recursos limitados que no son públicas, y que las personas de nuestra organización solo usan como máximo algunas veces al día. Cosas como Gitlab, Redmine, etc. Phusion Passenger puede reducir esos procesos cuando no se usan, y girarlos cuando se usan, permitiendo que haya más recursos disponibles para aplicaciones más importantes. Con otros servidores de aplicaciones, todos sus procesos están activados todo el tiempo.
  • Algunos servidores de aplicaciones no son buenos para ciertas cargas de trabajo, por diseño. Por ejemplo, Unicorn está diseñado solo para solicitudes de ejecución rápida: consulte la sección del sitio web de Unicornio "Simplemente peor en algunos casos".

Las cargas de trabajo en las que Unicornio no es bueno son:

  • Transmisión de cargas de trabajo (por ejemplo, transmisión en vivo de Rails 4 o transmisión de plantillas de Rails 4).
  • Cargas de trabajo en las que la aplicación realiza llamadas API HTTP.

El modelo híbrido de E / S en Phusion Passenger Enterprise 4 o posterior lo convierte en una excelente opción para este tipo de cargas de trabajo.

  • Otros servidores de aplicaciones requieren que el usuario ejecute al menos una instancia por aplicación. Por el contrario, Phusion Passenger admite múltiples aplicaciones en una sola instancia. Esto reduce en gran medida los gastos generales de administración.
  • Cambio automático de usuario, una característica de seguridad conveniente.
  • Phusion Passenger es compatible con muchos MRI Ruby, JRuby y Rubinius. Mongrel, Unicorn y Thin solo admiten resonancia magnética. Puma también es compatible con los 3.
  • ¡Phusion Passenger en realidad admite más que solo Ruby! También es compatible con Python WSGI, por lo que, por ejemplo, también puede ejecutar aplicaciones Django y Flask. De hecho, Phusion Passenger se está moviendo en la dirección de convertirse en un servidor políglota. Soporte de Node.js en la lista de tareas pendientes.
  • Recolección de basura fuera de banda. Phusion Passenger puede ejecutar el recolector de basura Ruby fuera del ciclo normal de solicitud / respuesta, reduciendo potencialmente los tiempos de solicitud en cientos de milisegundos. Unicorn también tiene una característica similar, pero la versión de Phusion Passenger es más flexible porque 1) no se limita a GC y puede usarse para trabajos arbitrarios. 2) La versión de Phusion Passenger funciona bien con aplicaciones multiproceso, mientras que la de Unicornio no.
  • Reinicios automáticos. Los reinicios continuos en Unicorn y otros servidores requieren un trabajo de secuencias de comandos. Phusion Passenger Enterprise automatiza completamente esta forma para usted.

Hay más características y ventajas, pero la lista es realmente larga. Debe consultar el manual completo de Phusion Passenger ( versión Apache , versión Nginx ) o el sitio web de Phusion Passenger para obtener información.

Modelos de concurrencia de E / S

  • Procesos múltiples de un solo hilo. Este es tradicionalmente el modelo de E / S más popular para los servidores de aplicaciones de Ruby, en parte porque el soporte de subprocesos múltiples en el ecosistema de Ruby era muy malo. Cada proceso puede manejar exactamente 1 solicitud a la vez. El servidor web equilibra la carga entre procesos. Este modelo es muy robusto y el programador tiene pocas posibilidades de introducir errores de concurrencia. Sin embargo, su concurrencia de E / S es extremadamente limitada (limitada por el número de procesos). Este modelo es muy adecuado para cargas de trabajo rápidas y de corta duración. Es muy inadecuado para cargas de trabajo de E / S de bloqueo lentas y de larga ejecución, por ejemplo, cargas de trabajo que involucran la llamada de API HTTP.
  • Puramente multiproceso. Hoy en día, el ecosistema Ruby tiene un excelente soporte de subprocesos múltiples, por lo que este modelo de E / S se ha vuelto muy viable. El subprocesamiento múltiple permite una alta concurrencia de E / S, lo que lo hace adecuado para cargas de trabajo de bloqueo de E / S de corto y largo plazo. Es más probable que el programador introduzca errores de concurrencia, pero afortunadamente la mayoría de los marcos web están diseñados de tal manera que esto todavía es muy poco probable. Sin embargo, una cosa a tener en cuenta es que el intérprete MRI Ruby no puede aprovechar múltiples núcleos de CPU incluso cuando hay múltiples hilos, debido al uso del bloqueo global del intérprete (GIL). Puede solucionar este problema mediante el uso de múltiples procesos de subprocesos múltiples, porque cada proceso puede aprovechar un núcleo de CPU. JRuby y Rubinius no tienen GIL, por lo que pueden aprovechar completamente múltiples núcleos en un solo proceso.
  • Híbrido multiproceso multiproceso. Principalmente implementado por Phusion Passenger Enterprise 4 y posterior. Puede cambiar fácilmente entre procesos multiproceso de un solo subproceso, puramente multiproceso o incluso múltiples procesos, cada uno con múltiples subprocesos. Este modelo ofrece lo mejor de ambos mundos.
  • Evented Este modelo es completamente diferente del modelo mencionado anteriormente. Permite una concurrencia de E / S muy alta y, por lo tanto, es excelente para cargas de trabajo de bloqueo de E / S de larga ejecución. Para utilizarlo, se requiere soporte explícito de la aplicación y el marco. Sin embargo, todos los marcos principales como Rails y Sinatra no son compatibles con el código de eventos. Es por eso que en la práctica un proceso Thin todavía no puede manejar más de 1 solicitud a la vez, lo que hace que se comporte de manera efectiva como el modelo multiproceso de un solo subproceso. Existen marcos especializados que pueden aprovechar las E / S desarrolladas, como Cramp.

Recientemente se publicó un artículo en el blog de Phusion sobre cómo optimizar de forma óptima la cantidad de procesos y subprocesos dada su carga de trabajo. Consulte Configuración de concurrencia de Tuning Phusion Passenger .

Capistrano

Capistrano es algo completamente diferente. En todas las secciones anteriores, "implementación" se refiere al acto de iniciar su aplicación Ruby en un servidor de aplicaciones, de modo que sea accesible para los visitantes, pero antes de que eso suceda, uno normalmente necesita hacer un trabajo de preparación, como:

  • Subir el código y los archivos de la aplicación Ruby a la máquina del servidor.
  • Instalar bibliotecas de las que depende su aplicación.
  • Configurar o migrar la base de datos.
  • Iniciar y detener cualquier demonio en el que pueda confiar su aplicación, como los trabajadores de Sidekiq / Resque o lo que sea.
  • Cualquier otra cosa que deba hacerse cuando configure su aplicación.

En el contexto de Capistrano, "despliegue" se refiere a hacer todo este trabajo de preparación. Capistrano no es un servidor de aplicaciones. En cambio, es una herramienta para automatizar todo ese trabajo de preparación. Le dice a Capistrano dónde está su servidor y qué comandos deben ejecutarse cada vez que implementa una nueva versión de su aplicación, y Capistrano se encargará de cargar la aplicación Rails en el servidor por usted y ejecutar los comandos que especificó.

Capistrano siempre se usa en combinación con un servidor de aplicaciones. No reemplaza a los servidores de aplicaciones. Viceversa, los servidores de aplicaciones no reemplazan a Capistrano, se pueden usar en combinación con Capistrano.

Por supuesto, no tienes que usar Capistrano. Si prefiere cargar su aplicación Ruby con FTP y ejecutar manualmente los mismos pasos de comandos cada vez, puede hacerlo. Otras personas se cansaron de eso, por lo que automatizan esos pasos en Capistrano.

Hongli
fuente
74
Deberías publicar esto en alguna parte. Ahora todo es fácil, pero cuando comencé con los rieles fue difícil obtener información útil.
spegoraro 01 de
99
Excelente post! Aclarado mucho para mí también. ¡Debe agregar algunos otros elementos como bundler y rvm y hacer que sea una publicación de blog impactante! :)
Damien Roche
37
Esto debe estar en las guías de Rails.
Dorian
44
"Nadie usa WEBrick en entornos de producción". Esto no es cierto en absoluto. El servidor de aplicaciones predeterminado al enviar aplicaciones ruby ​​a heroku es webrick.
John Downey
37
@Hongli Esta publicación es muy favorable para Phusion Passenger. ¿Quizás sería prudente agregar su afiliación al proyecto (CTO, phusion.nl/about ) por objetividad?
Bert Goethals