Pregunta Opciones de Ruby on Rails Server [cerrado]


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 juegan.

Empecé usando WEBrick, y ahora uso Mongrel para el desarrollo. ¿Son estos servidores autónomos, o se sientan frente a Apache?

He leído sobre Passenger y realmente no entiendo qué es, el sitio dice "hace que la implementación de aplicaciones web de Ruby sea sencilla", ¿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 de servidor de desarrollo?

Gracias


530
2017-11-06 13:37


origen


Respuestas:


La palabra "implementación" puede tener dos significados dependiendo del contexto. También está confundiendo los roles de Apache / Nginx con los roles de otros componentes.

Nota histórica: este artículo fue escrito originalmente el 6 de noviembre de 2010, cuando el ecosistema del servidor de aplicaciones Ruby era limitado. Actualicé este artículo el 15 de marzo de 2013 con todas las últimas actualizaciones del ecosistema.

Renuncia: 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, p. los escritos 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 hacer 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; Aprenderás más tarde por qué esto es relevante.

Mongrel y otros servidores de aplicaciones de producción frente a 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 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 regreso 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 abordaré más adelante y describiré cómo se diferencian entre sí y de Mongrel.

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

  • WEBrick no es apto para producción, a diferencia de todo lo demás que mencioné antes. WEBrick está escrito completamente en Ruby. Mongrel (y la mayoría de los otros servidores de aplicaciones 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 conocidos de análisis HTTP.
  • WEBrick generalmente solo se utiliza 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 utilizar 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é cambiaron a WEBrick.

El servidor de aplicaciones y el mundo

Todos los servidores actuales de la aplicación Ruby 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 estar directamente expuestos 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 gestionar 1 solicitud al mismo tiempo, por proceso. Si desea gestionar 2 solicitudes al mismo tiempo, debe ejecutar varias instancias del servidor de aplicaciones, cada una de ellas con la misma aplicación de Ruby. Este conjunto de procesos del servidor de aplicaciones se llama cluster de servidores de aplicaciones (de ahí el nombre de Mongrel Cluster, Thin Cluster, etc.). A continuación, debe configurar Apache o Nginx para revertir el proxy a 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 almacenar solicitudes y respuestas, protegiendo el servidor de la aplicación de los "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 que reciba la respuesta completa, porque durante ese tiempo el servidor de la aplicación no podrá hacer nada más. Apache y Nginx son muy buenos para hacer muchas cosas al mismo tiempo porque tienen múltiples subprocesos o tienen ventajas.
  • 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.
  • Normalmente, la gente configura Apache / Nginx para que sirva archivos estáticos directamente, pero reenvía 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 al servidor de aplicaciones de solicitudes corruptas (quizás malintencionadas).

¿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 The 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 corre 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.

  • Mestizo era bastante básico. Como se mencionó anteriormente, Mongrel es un proceso múltiple puramente de un único subproceso, 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), debe reiniciarse manualmente. La gente tiende a usar herramientas externas de monitoreo de procesos como Monit y Dios.
  • Unicornio es una bifurcación de Mongrel. 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 solo 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 proceso múltiple puramente de un único subproceso.
  • Delgado utiliza el modelo de E / S que se utiliza utilizando la biblioteca EventMachine. Además de usar el analizador HTTP Mongrel, no se basa en Mongrel de ninguna manera. Su modo de clúster no tiene supervisión de proceso, por lo que debe supervisar los bloqueos, etc. No hay un socket compartido parecido a Unicornio, 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 utiliza Thin, un proceso Thin solo puede manejar 1 solicitud simultánea, por lo que aún necesita un clúster. Obtenga más información acerca de esta peculiar propiedad en la sección "Modelos de simultaneidad de E / S".
  • Puma también se bifurcó de Mongrel, pero a diferencia de Unicorn, Puma está diseñado para ser puramente multiproceso. Por lo tanto, actualmente no hay soporte de clúster incorporado. Debe tener especial cuidado para asegurarse de que puede utilizar varios núcleos (más sobre esto en la sección "Modelos de simultaneidad de E / S").
  • Arcoiris 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 le permite a Apache servir aplicaciones PHP, casi mágicamente, Phusion Passenger permite a Apache (y también a Nginx!) Servir aplicaciones de Ruby, casi mágicamente. El objetivo de Phusion Passenger es hacer que todo funcione solo (tm) con la menor molestia posible.

En lugar de iniciar un proceso o clúster para su aplicación, y configurar Apache / Nginx para que sirva 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 la 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 prácticamente todo. No es necesario iniciar un clúster y administrar procesos. Iniciar / detener procesos, reiniciarlos cuando fallan, 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 principales razones por las que las personas usan Phusion Passenger.

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

También hay un Variante de empresa de Phusion Passenger con aún más características, tales como reinicios automáticos rodantes, soporte multihilo, resistencia al error de despliegue, etc.

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

Phusion Passenger vs otros servidores de aplicaciones

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

  • Ajuste dinámico de la cantidad de procesos en función del tráfico. Ejecutamos una gran cantidad de aplicaciones de Rails en nuestro servidor con recursos limitados que no son públicas, y que las personas de nuestra organización solo usan a lo sumo unas pocas veces al día. Cosas como Gitlab, Redmine, etc. Phusion Passenger puede reducir esos procesos cuando no se utilizan y hacerlos girar cuando se usan, lo que permite que haya más recursos disponibles para las 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: ver el sitio web de Unicornio sección "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, Rails 4 streaming en vivo o Rails 4 streaming de plantilla).
  • Cargas de trabajo en las que la aplicación realiza llamadas a la API HTTP.

El modelo de E / S híbrido en Phusion Passenger Enterprise 4 o más tarde 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 práctica función de seguridad.
  • Phusion Passenger es compatible con muchas resonancias magnéticas Ruby, JRuby y Rubinius. Mongrel, Unicorn y Thin solo son compatibles con MRI. Puma también es compatible con los 3.
  • ¡Phusion Passenger en realidad es compatible con algo más que 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, lo que puede 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 está limitado 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 automatizados. Los reinicios continuos en Unicorn y otros servidores requieren algún trabajo de scripting. Phusion Passenger Enterprise automatiza por completo esta manera 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 de Apache, Versión Nginx) o el sitio web de Phusion Passenger para información.

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 para que el programador introduzca errores de concurrencia. Sin embargo, su concurrencia de E / S es extremadamente limitada (limitada por la cantidad de procesos). Este modelo es muy adecuado para cargas de trabajo rápidas y de ejecución breve. Es muy inadecuado para cargas de trabajo de E / S de bloqueo lento y de larga ejecución, p. cargas de trabajo que implican la llamada de HTTP API.
  • Puramente multi-hilo. 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 multiprocesamiento permite una alta concurrencia de E / S, por lo que es 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 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 de MRI Ruby no puede aprovechar múltiples núcleos de CPU incluso cuando hay varios subprocesos, debido al uso del bloqueo de intérprete global (GIL). Puede solucionar esto utilizando múltiples procesos de subprocesos múltiples, ya que 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.
  • Multiproceso híbrido multiproceso. Principalmente implementado por Phusion Passenger Enterprise 4 y posterior. Puede cambiar fácilmente entre procesos múltiples de un único subproceso, puramente multiproceso o incluso múltiples procesos, cada uno con múltiples hilos. 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 E / S de bloqueo de larga ejecución. Para utilizarlo, se requiere soporte explícito de la aplicación y el marco. Sin embargo, todos los frameworks principales como Rails y Sinatra no son compatibles con código codificado. Esta es la razón por la cual, en la práctica, un proceso Fino aún no puede manejar más de 1 solicitud a la vez, por lo que se comporta efectivamente de la misma manera que el modelo multiproceso de subproceso único. Existen marcos especializados que pueden aprovechar las eficiencias de E / S, como Cramp.

Recientemente se publicó un artículo en el blog de Phusion sobre cómo optimizar la cantidad de procesos y subprocesos según su carga de trabajo. Ver Ajuste de la configuración de concurrencia de 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, para que sea accesible para los visitantes, pero antes de que eso suceda, normalmente se necesita hacer un trabajo de preparación, como por ejemplo:

  • Cargar el código y los archivos de la aplicación Ruby en 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 daemon en el que su aplicación pueda confiar, 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 y ejecutar los comandos que usted especificó.

Capistrano siempre se usa en combinación con un servidor de aplicaciones. No reemplaza 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 tener para 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, entonces automatizaron esos pasos en Capistrano.


1204