rails deploy app ruby-on-rails nginx webserver unicorn

ruby on rails - deploy - ¿Por qué Unicorn necesita ser desplegado junto con Nginx?



passenger rails app nginx (4)

Me gustaría saber la diferencia entre Nginx y Unicornio. Por lo que yo entiendo, Nginx es un servidor web mientras que Unicorn es un servidor Ruby HTTP.

Dado que tanto Nginx como Unicorn pueden manejar solicitudes HTTP, ¿cuál es la necesidad de usar la combinación de Nginx y Unicorn para aplicaciones RoR?


Esta respuesta es complementaria a las otras y explica por qué Unicorn necesita nginx en frente de ella .

TL; DR La razón por la que Unicorn se suele implementar junto con un proxy inverso como nginx se debe a que sus creadores lo diseñaron deliberadamente, lo que hace una compensación por simplicidad.

Antes que nada, no hay nada que te impida desplegar Unicorn sin un proxy inverso. Sin embargo, esa no sería una muy buena idea; veamos por qué.

Unicorn sigue la filosofía de Unix, que es hacer una cosa y hacerlo bien , y eso es servir clientes rápidos de baja latencia (veremos qué significa esto más adelante). El hecho de que Unicorn esté diseñado para clientes rápidos y de baja latencia también implica que no es muy bueno con clientes lentos y de alta latencia , lo cual es cierto. Este es uno de los puntos débiles de Unicorn y es donde entra en juego un proxy inverso: se sienta frente a Unicorn y se ocupa de esos clientes lentos (veremos cómo más adelante).

Afortunadamente, ese proxy inverso ya existe y se llama nginx .

La decisión de manejar solo clientes rápidos simplifica enormemente el diseño de Unicorn y permite una base de código mucho más simple y más pequeña, a costa de una mayor complejidad en el departamento de implementación (es decir, también debe implementar nginx además de Unicorn).

Una decisión alternativa podría ser diseñar unicornio de tal manera que no necesite un proxy inverso. Sin embargo, esto significa que tendría que implementar una funcionalidad adicional para hacer todas las cosas que ahora hace nginx, lo que da como resultado una base de código más compleja y más esfuerzos de ingeniería.

En cambio, sus creadores tomaron la decisión de aprovechar el software existente, probado en la batalla y muy bien diseñado, y para evitar perder tiempo y energía en problemas ya resueltos por otro software.

Pero pongámonos técnicos y respondamos a su pregunta:

¿Por qué Unicorn necesita ser desplegado junto con nginx?

Estas son algunas de las razones clave:

Unicorn usa bloqueo de E / S para clientes

Confiar en un proxy inverso significa que Unicorn no necesita usar E / S sin bloqueo. En cambio, puede usar E / S de bloqueo, que es intrínsecamente más simple y más fácil de seguir para el programador.

También como dice el documento DESIGN :

[Usar la E / S de bloqueo] permite seguir una ruta de código más simple dentro del intérprete de Ruby y menos llamadas de sistema.

Sin embargo, esto también tiene algunas consecuencias:

Punto clave n. ° 1: Unicorn no es eficiente con clientes lentos

(Por simplicidad, suponemos una configuración con 1 empleado de Unicorn)

Como se usa el bloqueo de E / S, un trabajador de Unicornio solo puede atender a un cliente a la vez , por lo que un cliente lento (es decir, uno con una conexión lenta) mantendría ocupado al trabajador durante más tiempo (de lo que haría un cliente rápido ) Mientras tanto, los otros clientes esperarían hasta que el trabajador vuelva a estar libre (es decir, las solicitudes se acumularían en la cola).

Para evitar este problema, se despliega un proxy inverso frente a Unicorn, que almacena por completo las solicitudes entrantes y las respuestas de la aplicación, y luego envía cada una de ellas al mismo tiempo (también conocido como "spoon-feeds") a Unicorn y a los clientes, respectivamente. En ese sentido, se podría decir que el proxy inverso "protege" a Unicorn de los clientes lentos de la red.

Afortunadamente Nginx es un gran candidato para este rol, ya que está diseñado para manejar miles de cientos de clientes simultáneos de manera eficiente.

Es de importancia crucial que el proxy inverso esté dentro de la misma red local que Unicorn (normalmente en la misma máquina física que se comunica con unicornio a través de un socket de dominio Unix), de modo que la latencia de la red se mantenga al mínimo.

Entonces, un proxy de este tipo desempeña efectivamente el papel de un cliente rápido que Unicorn está diseñado para servir en primer lugar, ya que envía solicitudes a Unicorn rápidamente y mantiene a los trabajadores ocupados durante el menor tiempo posible (en comparación con la cantidad de tiempo que un cliente con una conexión lenta haría).

Punto clave # 2: Unicorn no es compatible con HTTP / 1.1 keep-alive

Dado que Unicorn utiliza E / S de bloqueo, también significa que no puede admitir la característica HTTP-1.1 keep-alive, ya que las conexiones persistentes de clientes lentos ocuparían rápidamente todos los trabajadores de Unicorn disponibles.

Por lo tanto, para aprovechar HTTP keep-alive, adivina qué: se usa un proxy inverso.

nginx por otro lado, puede manejar miles de conexiones simultáneas usando solo unos pocos hilos. Por lo tanto, no tiene los límites de concurrencia que tiene un servidor como Unicorn (que esencialmente se limita a la cantidad de procesos de trabajo), lo que significa que puede manejar conexiones persistentes sin problemas. Se puede encontrar más información sobre cómo funciona esto realmente here .

Es por eso que nginx acepta conexiones keep-alive de los clientes y las envía a Unicorn por sobre conexiones simples a través de un socket Unix.

Punto # 3: Unicorn no es muy bueno para servir archivos estáticos

De nuevo, servir archivos estáticos es algo que Unicorn puede hacer pero no está diseñado para hacer de manera eficiente.

Por otro lado, los proxys inversos como nginx son mucho mejores en esto (es decir. sendfile(2) & caching).

Más

Hay otros puntos que se describen en el documento PHILOSOPHY (consulte "Rendimiento mejorado a través del proxy inverso" ).

Vea también algunas de las características básicas de nginx .

Vemos que aprovechando el software existente (es decir, nginx) y siguiendo la filosofía de Unix de "hacer una cosa y hacerlo bien", Unicorn es capaz de seguir un diseño e implementación más simples sin dejar de ser eficiente en la aplicación de aplicaciones Rack (por ej. su aplicación Rails).

Para obtener más información, consulte la PHILOSOPHY y DESIGN documentos de DESIGN Unicorn que explican con más detalle las opciones detrás del diseño de Unicorn y por qué nginx se considera un buen proxy inverso para Unicorn.


Nginx es un servidor web puro que está destinado a servir contenido estático y / o redirigir la solicitud a otro socket para gestionar la solicitud.

Unicorn es un servidor web Rack y solo tiene la intención de alojar una ''Rack App'' que generalmente genera contenido dinámico. Las aplicaciones en rack también pueden servir contenido estático pero es menos eficiente que la mayoría de los servidores web tradicionales.

La mayoría de las configuraciones RoR usan una combinación de servidores web tradicionales y servidores Rack para aplicar lo mejor de ambas capacidades. Nginx es increíblemente rápido en la redirección de solicitudes mediante el equilibrio de proxy y la publicación de contenido estático. Unicorn es bastante capaz de procesar encabezados HTTP y equilibrar las solicitudes entrantes a Ruby para su procesamiento.


Nginx se puede utilizar para servir clientes lentos en un servidor de unicornio ya que los clientes lentos podrían ahogar el servidor de unicornio. Nginx se usa como un tipo de proxy que almacena en búfer todas las solicitudes y respuestas a clientes lentos.

Ver http://unicorn.bogomips.org/