software - Opciones del servidor Ruby on Rails
ruby on rails tutorial (1)
Todo el problema de configurar un servidor de desarrollo para mi aplicación Ruby on Rails me confunde. Hay WEBrick, Mongrel, Passenger, Apache, Nginx y muchos más, estoy seguro, y realmente no entiendo los diferentes roles que desempeñan.
Comencé a usar WEBrick, y ahora uso Mongrel para el desarrollo. ¿Estos servidores son independientes o están frente a Apache?
He leído sobre Passenger y realmente no entiendo lo que es, el sitio dice "hace que el despliegue de aplicaciones web de Ruby sea muy fácil", ¿reemplaza a Mongrel? ¿Es como Capistrano, que también despliega 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 de servidor de desarrollo?
Gracias
La palabra "implementación" 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 de Ruby era limitado. He actualizado este artículo el 15 de marzo de 2013 con las últimas actualizaciones en el 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 adecuados, 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 eso necesitas 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 proxies 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ás por qué esto es relevante.
Mongrel y otros servidores de aplicaciones de producción vs WEBrick
Mongrel es un "servidor de aplicaciones" de Ruby: en términos concretos, esto significa que Mongrel es una aplicación que:
- Carga tu aplicación Ruby dentro de su propio espacio de proceso.
- 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 de Ruby.
- La aplicación web de Ruby luego devuelve un objeto, que describe cómo debería ser la respuesta HTTP, y Mongrel se encarga de convertirlo en una respuesta HTTP real (los bytes reales) y lo envía de vuelta a través del socket.
Sin embargo, el mestizo es bastante anticuado, hoy en día ya no se mantiene. Los nuevos servidores de aplicaciones alternativas son:
- Pasajero de phusion
- Unicornio
- Delgado
- Puma
- Trinidad (sólo JRuby)
- TorqueBox (solo JRuby)
Los cubriré más tarde y describiré cómo difieren 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é anteriormente. WEBrick está escrito enteramente en Ruby. Mongrel (y la mayoría de los otros servidores de aplicaciones de Ruby) es parte de 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 fugas de memoria conocidas y algunos problemas conocidos de análisis de HTTP.
- Generalmente, WEBrick solo se usa como servidor predeterminado durante el desarrollo porque WEBrick está incluido 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. Estaban usando Thin antes, así que no tengo idea de por qué 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 directamente expuestos a Internet en el puerto 80, mientras que otros no.
- Servidores de aplicaciones que pueden exponerse 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 omití.
¿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 a la vez, debe ejecutar varias instancias del servidor de aplicaciones, cada una de las cuales sirve a la misma aplicación de Ruby. Este conjunto de procesos del servidor de aplicaciones se denomina clúster de servidores de aplicaciones (de ahí el nombre Mongrel Cluster, Thin Cluster, etc.). Luego debe configurar Apache o Nginx para revertir el proxy a este clúster. Apache / Nginx se encargará de distribuir las solicitudes entre las instancias del clúster (más sobre esto en la sección "Modelos de concurrencia de E / S").
- El servidor web puede almacenar solicitudes y respuestas, protegiendo el servidor de aplicaciones de "clientes lentos": clientes HTTP que no envían ni aceptan datos muy rápidamente. No desea que su servidor de aplicaciones haga nada mientras espera que el cliente envíe la solicitud completa o reciba la respuesta completa, ya que durante ese tiempo el servidor de aplicaciones no podrá hacer nada más. Apache y Nginx son muy buenos para hacer muchas cosas al mismo tiempo porque son multiproceso o eventos.
- 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.
- Por lo general, las personas configuran Apache / Nginx para servir archivos estáticos directamente, pero las solicitudes de reenvío que no corresponden con archivos estáticos al servidor de aplicaciones, es una buena práctica de seguridad. Apache y Nginx son muy maduros y pueden proteger al servidor de aplicaciones de solicitudes dañadas (quizás de manera malintencionada).
¿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 ninguna 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 omití Trinidad y TorqueBox porque no los conozco lo suficiente, pero de todos modos solo son relevantes si usas JRuby.
- El mestizo era bastante esquivo. Como se mencionó anteriormente, Mongrel es multiproceso puramente de un solo hilo, por lo que solo es útil en un clúster. No hay supervisión 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 de monitoreo de procesos externos como Monit y Dios.
- Unicornio es un tenedor de mestizo. Admite la supervisión de procesos limitados: si un proceso falla, el proceso maestro lo reinicia automáticamente. Puede hacer que todos los procesos escuchen en un solo socket compartido, en lugar de un socket separado para cada proceso. Esto simplifica la configuración de proxy inverso. Al igual que Mongrel, es puramente multiproceso de un solo hilo.
- Thin utiliza el modelo de E / S de eventos utilizando la biblioteca EventMachine. Aparte de usar el analizador HTTP Mongrel, no está basado en Mongrel de ninguna manera. Su modo de clúster no tiene monitoreo de procesos, por lo que necesita monitorear fallos, 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 en las que se usa Thin, un proceso Thin solo puede manejar 1 solicitud concurrente, por lo que aún necesita un cluster. Más 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 multi-hilo. Por lo tanto, actualmente no hay soporte de clúster incorporado. Debe tener especial cuidado para asegurarse de que puede utilizar múltiples núcleos (más 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.
Pasajero de phusion
Phusion Passenger funciona de manera muy diferente a todos los demás. Phusion Passenger se integra directamente en Apache o Nginx, por lo que puede compararse 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!) Sirvan aplicaciones Ruby, casi mágicamente. El objetivo de Phusion Passenger es hacer que todo Just Work (tm) tenga 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 reenviar solicitudes de proxy al proceso / clúster con Phusion Passenger, solo necesita:
- Edita el archivo de configuración del servidor web y especifica la ubicación del directorio ''público'' de su aplicación Ruby.
- 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 partes móviles. Esta facilidad de uso es una de las razones principales por las que 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 incluso más funciones, como reinicios automáticos, soporte multihilo, resistencia a errores de despliegue, 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 vs otros servidores de aplicaciones
Phusion Passenger proporciona muchas más funciones y ofrece muchas ventajas sobre otros servidores de aplicaciones, como:
- Ajustando dinámicamente el número de procesos basados en el tráfico. Ejecutamos una gran cantidad de aplicaciones de Rails en nuestro servidor con recursos limitados que no son de acceso público, y que las personas de nuestra organización solo usan como máximo unas pocas veces al día. Cosas como Gitlab, Redmine, etc. Phusion Passenger puede reducir esos procesos cuando no se usan y aumentarlos cuando se usan, lo que permite 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 en 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 Unicorn "Just Worse in Some Cases".
Las cargas de trabajo en las que Unicorn no es bueno son:
- Transmisión de cargas de trabajo (por ejemplo, transmisión en vivo de Rails 4 o transmisión de plantilla de Rails 4).
- Cargas de trabajo en las que la aplicación realiza llamadas API HTTP.
El modelo de E / S híbrido 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 la sobrecarga de administración.
- Cambio automático de usuario, una característica de seguridad conveniente.
- Phusion Passenger soporta muchos MRI Ruby, JRuby y Rubinius. Mongrel, Unicorn y Thin solo son compatibles con MRI. Puma también soporta los 3.
- ¡Phusion Passenger en realidad es más compatible que Ruby! También es compatible con Python WSGI, por lo que 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, lo que podría reducir 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 de multiproceso, mientras que Unicorn no lo hace.
- Rolling automatizado reinicia. Los reinicios continuos en Unicorn y otros servidores requieren algunos trabajos de scripting. Phusion Passenger Enterprise se automatiza completamente de esta manera para usted.
Hay más características y ventajas, pero la lista es realmente larga. Para obtener más información, consulte el manual completo de Phusion Passenger ( versión Apache , versión Nginx ) o el sitio web de Phusion Passenger .
Modelos de concurrencia de E / S
- Multiproceso 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. Los balances de carga del servidor web entre procesos. Este modelo es muy robusto y hay pocas posibilidades de que el programador introduzca 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 ejecució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 multi-hilo. Hoy en día, el ecosistema de 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 E / S de bloqueo de ejecución corta y larga. Es más probable que el programador introduzca errores de concurrencia, pero afortunadamente la mayoría de los frameworks web están diseñados de tal manera que esto todavía es muy improbable. Sin embargo, una cosa a tener en cuenta es que el intérprete de MRI Ruby no puede aprovechar múltiples núcleos de CPU incluso cuando hay varios subprocesos, debido al uso del Bloqueo global de intérpretes (GIL). Puede solucionar este problema utilizando varios 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 al máximo múltiples núcleos en un solo proceso.
- Híbrido multiproceso multiproceso. Implementado principalmente por Phusion Passenger Enterprise 4 y versiones posteriores. Puede cambiar fácilmente entre multiproceso de un solo subproceso, multiproceso simple, o tal vez incluso varios procesos, cada uno con varios subprocesos. Este modelo da lo mejor de ambos mundos.
- Evento Este modelo es completamente diferente del modelo mencionado anteriormente. Permite una alta concurrencia de E / S y, por lo tanto, es excelente para cargas de trabajo de E / S con bloqueo de larga ejecución. Para utilizarlo, se requiere el soporte explícito de la aplicación y el marco. Sin embargo, todos los marcos principales como Rails y Sinatra no admiten código de eventos. Esta es la razón por la que, en la práctica, un proceso Thin aún 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 hilo. Hay marcos especializados que pueden aprovechar las E / S de eventos, como Cramp.
Recientemente se publicó un artículo en el blog de Phusion sobre la optimización óptima de la cantidad de procesos y subprocesos dada su carga de trabajo. Consulte la 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 ocurra, normalmente se necesita hacer un trabajo de preparación, como:
- Cargar el código y los archivos de la aplicación Ruby en la máquina del servidor.
- Instalar librerías de las que depende tu aplicación.
- Configuración o migración de la base de datos.
- Iniciar y detener cualquier daemons en el que pueda confiar su aplicación, como los trabajadores de Sidekiq / Resque o lo que sea.
- Cualquier otra cosa que deba hacerse al configurar 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 debe ejecutar cada vez que implemente una nueva versión de su aplicación, y Capistrano se encargará de cargar la aplicación Rails en el servidor y ejecutar los comandos que especificó.
Capistrano siempre se utiliza en combinación con un servidor de aplicaciones. No sustituye a los servidores de aplicaciones. Viceversa, los servidores de aplicaciones no reemplazan a Capistrano, se pueden usar en combinación con Capistrano.
Por supuesto que no tienes que usar Capistrano. Si prefiere cargar su aplicación Ruby con FTP y ejecutar los mismos pasos de comandos manualmente cada vez, puede hacerlo. Otras personas se cansaron de eso, por lo que automatizan esos pasos en Capistrano.