La primera versión del servidor HTTP Apache nace en 1995. Sin embargo, a día de hoy, más de 20 años después. El servidor web ruso nginx, que se pronuncia como “Engine-x”, también de código abierto, es el que posee una cuota de mercado mayor, creciendo de manera ex­po­ne­n­cial. Algo que resulta es­pe­cia­l­me­n­te doloroso para la Apache Fou­n­da­tion es que la mayoría de páginas web con una buena posición en el ranking de Alexa se entregan por medio de nginx, tal y como muestra un estudio es­ta­dí­s­ti­co de W3Techs que se actualiza re­gu­la­r­me­n­te. No solo los grandes bu­s­ca­do­res rusos como Rambler y Yandex, el servicio de correo ele­c­tró­ni­co Mail.RU o la red social VK utilizan el ligero servidor, sino que también pro­vee­do­res in­te­r­na­cio­na­les como Dropbox, Netflix, WordPress y FastMail utilizan nginx para mejorar el re­n­di­mie­n­to de sus servicios. ¿Significa esto que el Apache HTTP Server forma parte del pasado?

Nota

El servidor HTTP Apache, conocido en la comunidad in­te­r­nau­ta por su versión eco­no­mi­za­da “Apache”, es un proyecto de software impulsado bajo el pa­tro­ci­nio de la Apache Fou­n­da­tion. Esta co­n­ve­n­ción también se aplica a esta guía y al hablar de Apache se hace re­fe­re­n­cia al software y no al fa­bri­ca­n­te.

Los desafíos de la Web 2.0

Owen Garrett, re­s­po­n­sa­ble de productos de Nginx, Inc., describe al servidor web Apache en el blog de nginx.com en 2015 como el “backbone” (columna vertebral) de la Web 1.0 y pone de relieve su im­po­r­ta­n­cia para el de­sa­rro­llo de Internet alrededor del cambio de milenio. El notable éxito del servidor web reside en la sencilla ar­qui­te­c­tu­ra del software, si bien se basa en de­ci­sio­nes de diseño orie­n­ta­das a una World Wide Web que no se puede comparar con la actual. Hace 20 años las páginas web tenían una es­tru­c­tu­ra más simple, el ancho de banda era limitado y caro y, por el contrario, el tiempo de la CPU era en co­m­pa­ra­ción más económico. 

Hoy en día estamos ante una World Wide Web de segunda ge­ne­ra­ción que muestra una cara muy diferente: tanto el número de usuarios como el tráfico web mundial se han mu­l­ti­pli­ca­do y lo mismo se puede decir del tamaño medio de las páginas así como de la cantidad de co­m­po­ne­n­tes que los na­ve­ga­do­res deben consultar y re­n­de­ri­zar para poderlas re­pre­se­n­tar. Una parte cada vez mayor de la comunidad en Internet ha crecido aco­s­tu­m­bra­da a las po­si­bi­li­da­des de la Web 2.0 y este grupo de usuarios no está habituado a esperar varios segundos y mucho menos minutos para descargar una página web.

Estos cambios han supuesto en los últimos años un desafío cada vez mayor para el servidor HTTP Apache. Owen Garret señala como re­s­po­n­sa­ble a la ar­qui­te­c­tu­ra basada en procesos propia de Apache, que no se puede escalar ade­cua­da­me­n­te a la vista de un tráfico cada vez más elevado. Esta debilidad fue una de las pri­n­ci­pa­les mo­ti­va­cio­nes para de­sa­rro­llar nginx en el año 2002, que fue por unos de­rro­te­ros di­fe­re­n­tes debido a su ar­qui­te­c­tu­ra dirigida por eventos. nginx fue creado por el de­sa­rro­lla­dor de software ruso Igor Sysoev, se utiliza tanto como servidor web como proxy inverso o proxy de correo ele­c­tró­ni­co y está diseñado ate­n­die­n­do a las ne­ce­si­da­des del buscador ruso Rambler.

A co­n­ti­nua­ción te hablamos de la relación entre Apache y nginx y te in­fo­r­ma­mos sobre las di­fe­re­n­cias ar­qui­te­c­tó­ni­cas, la co­n­fi­gu­ra­ción o las po­si­bi­li­da­des de de­sa­rro­llo, pero también sobre la co­m­pa­ti­bi­li­dad, la do­cu­me­n­ta­ción y la asi­s­te­n­cia técnica.

Consejo

Para obtener una in­tro­du­c­ción general sobre la in­s­ta­la­ción y co­n­fi­gu­ra­ción de ambos se­r­vi­do­res web open source, visita nuestros artículos sobre Apache y NGINX.

Di­fe­re­n­cias ar­qui­te­c­tó­ni­cas

Los se­r­vi­do­res web Apache y nginx presentan di­fe­re­n­cias en cuanto a la ar­qui­te­c­tu­ra del software en relación con la gestión de la conexión, la in­te­r­pre­ta­ción de las so­li­ci­tu­des de los clientes, el manejo de los co­n­te­ni­dos web estáticos y dinámicos y la co­n­fi­gu­ra­ción.

Gestión de la conexión

En la co­m­pa­ra­ción de nginx vs. Apache surgen di­fe­re­n­cias básicas en la manera como manejan las so­li­ci­tu­des entrantes de los clientes (requests). Mientras que Apache parte de una ar­qui­te­c­tu­ra basada en procesos, la gestión de la conexión en nginx se erige sobre la base de un algoritmo de pro­ce­sa­mie­n­to dirigido por eventos, lo que permite procesar so­li­ci­tu­des ahorrando recursos incluso cuando entran en juego varias co­ne­xio­nes si­mu­l­tá­nea­me­n­te. Esto co­n­s­ti­tu­ye, según los de­sa­rro­lla­do­res de nginx, una gran ventaja frente al servidor HTTP Apache, que desde la versión 2.4 ofrece la po­si­bi­li­dad de im­ple­me­n­tar eventos. Veamos a co­n­ti­nua­ción las di­fe­re­n­cias en detalle.

El servidor web Apache adopta un enfoque en el que las so­li­ci­tu­des de los clientes se tramitan en un proceso o thread (hilo) separado. El single threading o proceso con un único hilo, el modo operativo original del Apache HTTP server, plantea problemas tarde o temprano con el bloqueo de I/O: los procesos que requieren ope­ra­cio­nes de escritura o lectura se procesan es­tri­c­ta­me­n­te uno tras otro. Así, la solicitud posterior pe­r­ma­ne­ce­rá en espera hasta que se haya re­s­po­n­di­do a la anterior. Esto se puede evitar iniciando varios procesos de single threading si­mu­l­tá­nea­me­n­te, una es­tra­te­gia que conlleva un consumo elevado de recursos.

Como al­te­r­na­ti­va pueden usarse me­ca­ni­s­mos de mu­l­ti­th­rea­di­ng o de mu­l­ti­hi­los. A di­fe­re­n­cia del single threading, en el que en todo proceso hay di­s­po­ni­ble un thread para responder a las so­li­ci­tu­des de los clientes, el mu­l­ti­th­rea­di­ng ofrece la po­si­bi­li­dad de ejecutar varios hilos en un mismo proceso. Como los hilos de Linux necesitan menos recursos que procesos, el mu­l­ti­th­rea­di­ng permite compensar las amplias ne­ce­si­da­des de recursos de la ar­qui­te­c­tu­ra basada en procesos del servidor HTTP Apache.

Para integrar me­ca­ni­s­mos que permitan el pro­ce­sa­mie­n­to paralelo de pe­ti­cio­nes en Apache puede re­cu­rri­r­se a uno de estos tres módulos de mu­l­ti­pro­ce­sa­mie­n­to (MPM): mpm_prefork, mpm_worker, mpm_event.

  • mpm_prefork: el módulo de Apache “prefork” garantiza la gestión mu­l­ti­pro­ce­so basándose en un mecanismo de single threading. El módulo crea un proceso padre que ofrece múltiples procesos hijo y en cada uno de ellos funciona un thread o hilo que permite responder a la solicitud del cliente. Siempre que haya más procesos single thread di­s­po­ni­bles que pe­ti­cio­nes entrantes de clientes, las requests se pro­ce­sa­rán de manera inmediata.
    El número de procesos de single threading di­s­po­ni­bles se define con ayuda de las opciones de co­n­fi­gu­ra­ción del servidor “Mi­n­S­pa­re­Se­r­ve­rs” y “Ma­x­S­pa­re­Se­r­ve­rs”. El módulo prefork alberga, sin embargo, los in­co­n­ve­nie­n­tes de re­n­di­mie­n­to del single threading an­te­rio­r­me­n­te me­n­cio­na­dos, si bien la in­de­pe­n­de­n­cia de los procesos resulta ventajosa: si se pierde la conexión debido a un proceso de­fe­c­tuo­so, por lo general esto no se refleja en las co­ne­xio­nes editadas en otros procesos.
  • mpm_worker: con el módulo “worker”, Apache ofrece a los usuarios un mecanismo de mu­l­ti­th­rea­di­ng para el pro­ce­sa­mie­n­to paralelo de las so­li­ci­tu­des de los clientes. El número de threads que debe iniciarse por proceso puede de­te­r­mi­nar­se con la opción de co­n­fi­gu­ra­ción del servidor “Th­rea­d­s­Pe­r­Chi­ld”. El módulo prevé un thread por conexión TCP.  Siempre que haya más procesos di­s­po­ni­bles que so­li­ci­tu­des entrantes, las requests se procesan en paralelo. El proceso padre (httpd) vigila los threads des­ocu­pa­dos.
    Los usuarios pueden recurrir a los comandos “Mi­n­S­pa­re­Th­rea­ds” y “Ma­x­S­pa­re­Th­rea­ds” para definir a partir de qué cantidad de hilos des­ocu­pa­dos deben generarse nuevos threads o eli­mi­nar­se de la memoria ciertos hilos en ejecución. El módulo worker no necesita tantos recursos como el prefork. Puesto que las co­ne­xio­nes no se procesan en procesos separados, un thread de­fe­c­tuo­so pude re­pe­r­cu­tir en el pro­ce­di­mie­n­to completo de mu­l­ti­th­rea­di­ng y en todas las co­ne­xio­nes que se elaboran en él. Además, tanto worker como prefork son propensos a las so­bre­ca­r­gas a través de las llamadas co­ne­xio­nes Keep Alive (véase más abajo).
  • mpm_event: desde la versión 2.4, el servidor HTTP Apache ofrece el tercer módulo de mu­l­ti­pro­ce­s­si­ng llamado event, que está destinado a un entorno pro­du­c­ti­vo. Este es una variante del módulo worker y se ocupa de la di­s­tri­bu­ción de carga entre los hilos iniciados. A ello se añade un listener thread por proceso de mu­l­ti­th­rea­di­ng, que se encarga de las so­li­ci­tu­des de los clientes y asigna para ello tareas re­la­cio­na­das en hilos del módulo worker. El módulo event fue de­sa­rro­lla­do para optimizar la relación con las co­ne­xio­nes Keep Alive, es decir, co­ne­xio­nes TCP que no deben contener ningún tipo de fallos para po­si­bi­li­tar la tra­n­s­mi­sión de otras so­li­ci­tu­des de los clientes o de las re­s­pue­s­tas de los se­r­vi­do­res (responses). Si se recurre al clásico módulo worker, sus hilos mantienen las co­ne­xio­nes es­ta­ble­ci­das y, por lo tanto, se bloquean incluso si no se recibe ninguna otra solicitud, lo que, en caso de una gran cantidad de co­ne­xio­nes Keep Alive puede dar lugar a la so­bre­ca­r­ga del servidor. Por el contrario, el módulo event ex­te­r­na­li­za el ma­n­te­ni­mie­n­to de co­ne­xio­nes Keep Alive en el listener thread in­de­pe­n­die­n­te. Así, los hilos de worker no se bloquean y están di­s­po­ni­bles para procesar otras so­li­ci­tu­des.

El siguiente gráfico muestra una pre­se­n­ta­ción es­que­má­ti­ca de la ar­qui­te­c­tu­ra basada en procesos del servidor web Apache uti­li­za­n­do el módulo worker:

De­pe­n­die­n­do del módulo utilizado, Apache soluciona el problema de la co­n­cu­rre­n­cia (que también hace re­fe­re­n­cia a la respuesta si­mu­l­tá­nea a varias so­li­ci­tu­des de clientes) ya sea mediante procesos adi­cio­na­les o mediante threads. Ambas es­tra­te­gias van aco­m­pa­ña­das de unos costes adi­cio­na­les, lo que se convierte en un factor limitante a la hora de escalar un servidor Apache.

La enorme necesidad de recursos del principio “un proceso por conexión” se debe al hecho de que para cada proceso adicional se tiene que facilitar un entorno de tiempo de ejecución propio, el cual requiere la asi­g­na­ción del tiempo de la CPU y de una memoria separada. Además, todo módulo de Apache que tenga que estar di­s­po­ni­ble en un proceso worker debe cargarse por separado. Por el contrario, los hilos comparten un entorno de ejecución (el programa) y un espacio para di­re­c­cio­nes en la memoria. La so­bre­ca­r­ga de los hilos adi­cio­na­les es, por lo tanto, inferior a la de los procesos. Sin embargo, el mu­l­ti­th­rea­di­ng requiere muchos recursos en lo que a cambios de contexto (context switches) se refiere.

Estos cambios de contexto hacen re­fe­re­n­cia al pro­ce­di­mie­n­to por el que el sistema de un proceso o hilo se cambia por otro, para lo que tiene que pro­te­ge­r­se el contexto del proceso o hilo fi­na­li­za­do y generarse o re­s­ta­ble­ce­r­se el nuevo, co­n­vi­r­tié­n­do­se así en un pro­ce­di­mie­n­to ad­mi­ni­s­tra­ti­vo que requiere mucho tiempo y en el que tanto el registro de la CPU como las diversas tablas y listas han de cargarse y pro­te­ge­r­se.

El módulo mpm_event contiene un mecanismo event para el servidor HTTP Apache que ex­te­r­na­li­za la edición de las co­ne­xio­nes entrantes en un hilo listener. Este permite finalizar co­ne­xio­nes que ya no son ne­ce­sa­rias (también las co­ne­xio­nes Keep Alive) y, así, reducir el consumo de recursos. Sin embargo, el problema de los cambios de contexto que requieren muchos recursos no se soluciona si el hilo listener traslada las requests de las co­ne­xio­nes ma­n­te­ni­das a hilos worker separados.

Por el contrario, la ar­qui­te­c­tu­ra basada en eventos de nginx realiza la co­n­cu­rre­n­cia sin que sea necesario un proceso o hilo adicional para cada conexión nueva, y es que un único pro­ce­di­mie­n­to nginx es capaz de procesar miles de co­ne­xio­nes HTTP si­mu­l­tá­nea­me­n­te. Esto se lleva a cabo mediante un mecanismo de bucles conocido como event loop o bucle de eventos, que permite procesar las so­li­ci­tu­des de los clientes de manera asi­n­cró­ni­ca en un hilo.

Consejo

En teoría, nginx recurre al pro­ce­sa­mie­n­to de co­ne­xio­nes con un solo proceso de single threading. Por lo general, para poder sacar todo el provecho al hardware, el servidor web se inicia con un proceso worker por núcleo de pro­ce­sa­dor (CPU) de la máquina su­b­ya­ce­n­te.

A di­fe­re­n­cia del servidor web Apache, en el que se puede limitar el número de procesos o hilos activos con valores mínimos o máximos, nginx ofrece un modelo de procesos pre­de­ci­ble que se ajusta con exactitud al hardware su­b­ya­ce­n­te. Dicho modelo comprende un proceso maestro, los pro­ce­sa­do­res de ayuda cache loader y cache manager, así como un número de pro­ce­sa­do­res worker adaptados a los di­fe­re­n­tes núcleos de pro­ce­sa­do­res y definidos cla­ra­me­n­te por medio de la co­n­fi­gu­ra­ción.

  • Proceso maestro: el proceso maestro es un proceso padre que ejecuta las ope­ra­cio­nes básicas como, por ejemplo, la lectura de la co­n­fi­gu­ra­ción del servidor, la unión de puertos y la creación de todos los tipos de procesos si­guie­n­tes.
  • Procesos co­la­bo­ra­do­res: nginx utiliza dos procesos para gestionar el caché, es decir, el cache loader y el cache manager.
    • Cache loader: el cache loader es re­s­po­n­sa­ble de que el caché basado en el disco duro se cargue en la memoria.
    • Cache manager: la tarea del cache manager es controlar que los registros del caché del disco duro muestren las di­me­n­sio­nes pre­via­me­n­te co­n­fi­gu­ra­das y las re­s­tri­n­jan según las ne­ce­si­da­des. Este proceso se activa pe­rió­di­ca­me­n­te.
  • Proceso worker: los procesos worker son re­s­po­n­sa­bles del pro­ce­sa­mie­n­to de co­ne­xio­nes, del acceso de escritura y lectura en el disco duro y de la co­mu­ni­ca­ción con se­r­vi­do­res upstream (se­r­vi­do­res que pro­po­r­cio­nan servicios a otros se­r­vi­do­res). En otras palabras, son los únicos procesos del modelo de procesos de nginx que están co­n­ti­nua­me­n­te activos.

El siguiente gráfico muestra una re­pre­se­n­ta­ción es­que­má­ti­ca del modelo de procesos de nginx: 

Todos los procesos worker que inicia el proceso maestro de nginx en el marco de la co­n­fi­gu­ra­ción comparten un set de listener sockets (puntos finales de co­mu­ni­ca­ción). En lugar de iniciar un proceso o hilo propio para cada conexión entrante, en cada proceso worker se ejecuta un event loop que po­si­bi­li­ta el pro­ce­sa­mie­n­to asi­n­cró­ni­co de varios miles de co­ne­xio­nes en un mismo hilo sin bloquear el proceso. Para ello, los procesos worker escuchan en los listener sockets ate­n­ta­me­n­te a los eventos pro­du­ci­dos a través de co­ne­xio­nes entrantes, los aceptan y ejecutan procesos de lectura y escritura en el socket durante el pro­ce­sa­mie­n­to de pe­ti­cio­nes HTTP. 

En este contexto, nginx no provee de ningún mecanismo propio para la di­s­tri­bu­ción de co­ne­xio­nes en procesos worker. En lugar de ello se utilizan las funciones centrales del sistema operativo. Los esquemas sobre cómo procesar las so­li­ci­tu­des entrantes se preparan a través de máquinas de estados (state machines) separadas para HTTP, raw TCP, SMTP, IMAP y POP3.

En términos más generales, nginx puede ser de­no­mi­na­do como ad­mi­ni­s­tra­dor de eventos, ya que recibe datos sobre eventos del kernel y comunica al sistema operativo cómo tiene que gestionar las tareas re­la­cio­na­das. El pro­ce­sa­mie­n­to asi­n­cró­ni­co de tareas en el event loop se basa en no­ti­fi­ca­cio­nes de eventos, de­vo­lu­cio­nes de llamada (callbacks) y te­m­po­ri­za­do­res. Estos me­ca­ni­s­mos permiten que un proceso worker delegue una operación tras otra en el sistema operativo sin tener que esperar con pasividad al resultado de la operación o a la respuesta de los programas cliente. Por lo tanto, nginx funciona como or­que­s­ta­dor para el sistema operativo, que se encarga de leer y escribir bytes.

Este tipo de gestión de la conexión solo genera una ligera so­bre­ca­r­ga para las co­ne­xio­nes adi­cio­na­les. Todo lo que se necesita es un File De­s­cri­p­tor (FD) adicional y una mínima memoria adicional en el proceso worker. Por el contrario, los cambios de contexto que requieren una re­n­de­ri­za­ción intensiva se presentan cuando en un event loop no aparecen otros eventos. La efe­c­ti­vi­dad a la hora de tramitar las so­li­ci­tu­des mediante un número elevado de co­ne­xio­nes pre­de­s­ti­na a nginx como di­s­tri­bui­dor de carga para páginas web muy fre­cue­n­ta­das, como por ejemplo WordPress.com.

En resumen

Con una ar­qui­te­c­tu­ra que soporta eventos, nginx ofrece una al­te­r­na­ti­va a la gestión de co­ne­xio­nes del servidor HTTP Apache basada en procesos, pero esta ca­ra­c­te­rí­s­ti­ca no es su­fi­cie­n­te por sí misma para explicar por qué nginx saca tan buena nota en los tests Benchmark, pues desde la versión 2.4, Apache también soporta un mecanismo de pro­ce­sa­mie­n­to de las so­li­ci­tu­des de los clientes basado en eventos. En co­m­pa­ra­ti­vas de se­r­vi­do­res web del tipo Apache vs. nginx se debe prestar siempre atención, por ello, a los módulos uti­li­za­dos por los se­r­vi­do­res web para realizar los tests, a la co­n­fi­gu­ra­ción de los se­r­vi­do­res y a las tareas que deben afro­n­tar­se.

Gestión de los co­n­te­ni­dos web estáticos y dinámicos

En lo que respecta al manejo de los co­n­te­ni­dos web dinámicos, nginx sigue una es­tra­te­gia to­ta­l­me­n­te diferente a la del servidor HTTP Apache.

En principio, para poder entregar co­n­te­ni­dos web dinámicos, un servidor web debe recurrir a un in­té­r­pre­te que tenga la capacidad de procesar el lenguaje de pro­gra­ma­ción necesario, como PHP, Perl, Python o Ruby. Para ello, Apache contiene diversos módulos como mod_php, mod_perl, mod_python o mod_ruby, que permiten cargar el in­té­r­pre­te co­rre­s­po­n­die­n­te di­re­c­ta­me­n­te en el servidor web, de forma que posee de entrada la habilidad de procesar co­n­te­ni­dos web dinámicos. Las funciones para la provisión de co­n­te­ni­dos estáticos se im­ple­me­n­tan por medio de los módulos MPM an­te­rio­r­me­n­te me­n­cio­na­dos.

Por el contrario, nginx solo ofrece me­ca­ni­s­mos para pro­po­r­cio­nar co­n­te­ni­dos web estáticos y la entrega de co­n­te­ni­dos dinámicos se ex­te­r­na­li­za en se­r­vi­do­res de apli­ca­cio­nes es­pe­cia­li­za­dos. En este caso, nginx hace de proxy entre el programa cliente y el servidor upstream. La co­mu­ni­ca­ción tiene lugar a través de pro­to­co­los como HTTP, FastCGI, SCGI, uWSGI y Memcached. WebSphere, JBoss o Tomcat se erigen como posibles se­r­vi­do­res de apli­ca­cio­nes para la entrega de co­n­te­ni­dos dinámicos, aunque también puede uti­li­zar­se el servidor HTTP Apache.

Ambas es­tra­te­gias presentan ventajas e in­co­n­ve­nie­n­tes. Un módulo como mod_php permite al servidor web ejecutar código PHP y no se necesita para ello un servidor de apli­ca­cio­nes adicional, lo que hace más cómoda la ad­mi­ni­s­tra­ción de páginas web dinámicas. Los módulos in­té­r­pre­te para los lenguajes de pro­gra­ma­ción dinámicos tienen que cargarse por separado en cada proceso worker, al que se le en­co­mie­n­da la entrega del contenido. Si se da un gran número de procesos worker, esto conlleva una clara so­bre­ca­r­ga que nginx puede reducir, ya que solo se recurre al in­té­r­pre­te ex­te­r­na­li­za­do en caso necesario.

Mientras que nginx está orientado a la in­ter­ac­ción con un in­té­r­pre­te ex­te­r­na­li­za­do, los usuarios de Apache pueden recurrir a ambas es­tra­te­gias. Apache también puede emplearse para un servidor de apli­ca­cio­nes que se encargue de la in­te­r­pre­ta­ción de co­n­te­ni­dos web dinámicos. Por lo general, se utiliza el protocolo FastCGI, y la interfaz co­rre­s­po­n­die­n­te se carga con el módulo mod_proxy_fcgi.

En resumen

En la co­m­pa­ra­ción Apache vs. nginx ambos se­r­vi­do­res web permiten entregar páginas web dinámicas. Mientras que Apache in­te­r­pre­ta por sí mismo y ejecuta el código de programa utilizado con ayuda de módulos, nginx confía esta tarea a un servidor de apli­ca­cio­nes externo.

In­te­r­pre­ta­ción de las so­li­ci­tu­des de los clientes

Para responder sa­ti­s­fa­c­to­ria­me­n­te a las pe­ti­cio­nes de los programas cliente, los se­r­vi­do­res deben de­te­r­mi­nar cuáles son los recursos so­li­ci­ta­dos y donde se en­cue­n­tran basándose en la propia request.

El servidor HTTP Apache fue concebido como servidor web. Por el contrario, nginx ofrece tanto funciones de servidor web como de servidor proxy, di­fe­re­n­cia que se vuelve a ma­ni­fe­s­tar sobre todo en la manera en que el software co­rre­s­po­n­die­n­te in­te­r­pre­ta las so­li­ci­tu­des de los clientes y clasifica los recursos en el servidor. 

Nota

El servidor HTTP Apache se puede utilizar como servidor proxy con ayuda del módulo mod_proxy.

Tanto el servidor HTTP Apache como nginx cuentan con me­ca­ni­s­mos que permiten in­te­r­pre­tar requests entrantes como recursos físicos en el sistema de archivos o como URI (Uniform Resource Ide­n­ti­fier). Mientras Apache trabaja no­r­ma­l­me­n­te en base a archivos, en nginx se da prioridad a los URI.

Si llega una solicitud de cliente al servidor HTTP Apache, este presupone, por lo general, que se debe consultar un recurso es­pe­cí­fi­co del sistema de archivos del servidor. Debido a que con los Vi­r­tua­lHo­sts Apache ofrece la po­si­bi­li­dad de pro­po­r­cio­nar di­fe­re­n­tes co­n­te­ni­dos web en un mismo servidor bajo diversos nombres de host, di­re­c­cio­nes IP o números de puerto, se debe indicar a qué Vi­r­tua­lHo­st hace re­fe­re­n­cia la solicitud. Para ello, el servidor web coteja el nombre del host, la dirección IP y el número del puerto al principio del URI de la petición con los Vi­r­tua­lHo­sts definidos en el fichero de co­n­fi­gu­ra­ción principal httpd.conf.

El siguiente ejemplo de código muestra una co­n­fi­gu­ra­ción de Apache en la que los dos dominios www.example.com y www.other-example.com se operan bajo la misma dirección IP:

NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com *.example.com
DocumentRoot /data/www/example
</VirtualHost>
<VirtualHost *:80>
ServerName www.other-example.com
DocumentRoot /data/www/other-example
</VirtualHost>

El asterisco (*) sirve como es­pa­cia­dor para cualquier dirección IP. Mediante la co­m­pa­ra­ción del nombre de host incluido en la solicitud con la directiva Se­r­ve­r­Na­me Apache decide en qué Do­cu­me­n­tRoot (di­re­c­to­rio de inicio de un proyecto web) se debe buscar el recurso so­li­ci­ta­do.

Si Apache ha en­co­n­tra­do el servidor deseado, el URI de la solicitud se proyecta por defecto en el sistema de archivos del servidor (mapping). Para ello, Apache emplea la ruta de acceso incluida en el URI y, en co­m­bi­na­ción con el Do­cu­me­n­tRoot, se genera la ruta del recurso.

En una solicitud con el URI "http://www.example.org:80/public_html/images/logo.gif", Apache  buscaría (partiendo del ejemplo anterior) el recurso adecuado siguiendo la ruta de archivo que aparece a co­n­ti­nua­ción :

/data/www/example/public_html/images/logo.gif
Nota

Debido a que 80 es el puerto estándar para HTTP, en la práctica no­r­ma­l­me­n­te se prescinde de este dato.

Apache compara el URI de la solicitud con los bloques file y directory op­cio­na­les en la co­n­fi­gu­ra­ción. Estos permiten definir in­s­tru­c­cio­nes es­pe­cia­les para las requests a las que se hace re­fe­re­n­cia en los archivos o di­re­c­to­rios (incluidos los su­b­di­re­c­to­rios) se­le­c­cio­na­dos.

En el siguiente ejemplo se definen in­s­tru­c­cio­nes es­pe­cia­les para el di­re­c­to­rio public_html/images y el fichero private.html:

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com *.example.com
    DocumentRoot /data/www/example
      <Directory var/www/example.com/public_html/images>
          Order Allow,Deny
          Allow from all
     </Directory> 
      <Files public.html>
          Order Allow,Deny
          Deny from all
      </Files>
</VirtualHost>

Además de este pro­ce­di­mie­n­to habitual en la in­te­r­pre­ta­ción de las so­li­ci­tu­des de los clientes, con la directiva Alias Apache ofrece la po­si­bi­li­dad de indicar un di­re­c­to­rio al­te­r­na­ti­vo que tiene que analizar el recurso so­li­ci­ta­do en lugar del Do­cu­me­n­tRoot. Asimismo, el módulo mod_rewrite del servidor HTTP Apache permite a los usuarios describir o reenviar URL.

Nota

Puedes obtener más in­fo­r­ma­ción sobre el módulo mod_rewrite en nuestro artículo sobre cómo re­es­cri­bir URL con mod_rewrite.

Cuando Apache tiene que consultar recursos de­po­si­ta­dos fuera del sistema de archivos del servidor, se utiliza la directiva Location (ubicación), que permite definir in­s­tru­c­cio­nes para de­te­r­mi­na­dos URI.

Lo que puede ser una excepción en Apache, se convierte en algo estándar en nginx, que analiza el URI de la solicitud y lo compara con los bloques server y location en la co­n­fi­gu­ra­ción del servidor web. Solo después puede tener lugar (si es necesario) el mapeo en el sistema de archivos y la co­m­bi­na­ción con el root (Do­cu­me­n­tRoot del servidor Apache).

Con ayuda de la directiva Server (servidor), nginx averigua qué host es el re­s­po­n­sa­ble de responder a la solicitud del cliente. El bloque server co­rre­s­po­n­de a un Vi­r­tua­lHo­st en la co­n­fi­gu­ra­ción de Apache. Para ello se deben si­n­cro­ni­zar el nombre del host, la dirección IP y el número del puerto del URI de la solicitud con todos los bloques server en la co­n­fi­gu­ra­ción del servidor web. El siguiente ejemplo de código muestra tres bloques server en el fichero de co­n­fi­gu­ra­ción de nginx nginx.conf:

server {
    listen 80;
    server_name example.org www.example.org;
    ...
}
server {
    listen 80;
    server_name example.net www.example.net;
    ...
}
server {
    listen 80;
    server_name example.com www.example.com;
    ...
}
Nota

Todos los bloques de servidor suelen contener una serie de bloques de ubicación. En el ejemplo actual estos se su­s­ti­tu­yen por un es­pa­cia­dor (...).

La co­m­pa­ra­ción entre el URI de la solicitud y los bloques location en un bloque server se realiza solo cuando se encuentra el servidor so­li­ci­ta­do. Para ello, nginx lee los bloques de ubicación es­pe­ci­fi­ca­dos y busca la ubicación más acorde con el URI de la solicitud. Los bloques location contienen in­s­tru­c­cio­nes es­pe­cí­fi­cas que indican a nginx cómo se tiene que tramitar la solicitud co­rre­s­po­n­die­n­te.

Aquí se pueden definir las ubi­ca­cio­nes de manera que se in­te­r­pre­ten como prefijo para una ruta, como coin­ci­de­n­cia exacta o como expresión regular (Regular Ex­pre­s­sion, RegEx). En la sintaxis de la co­n­fi­gu­ra­ción del servidor se utilizan, entre otros, los si­guie­n­tes mo­di­fi­ca­do­res:

Sin mo­di­fi­ca­dor La directiva Location se in­te­r­pre­ta como prefijo. Todas las requests cuyo URI muestra el prefijo definido en la directiva Location son co­n­si­de­ra­das conforme a dicha location. Si no se encuentra una location es­pe­cí­fi­ca, la solicitud se procesa según los datos del bloque ubicación.
= La directiva Location se in­te­r­pre­ta como co­rre­s­po­n­de­n­cia exacta. Todas las requests con co­rre­s­po­n­de­n­cia exacta cuyo URI coincida exac­ta­me­n­te con la secuencia de ca­ra­c­te­res de la directiva Location se procesan según los datos en el bloque ubicación.
 ~ La directiva Location se in­te­r­pre­ta como expresión regular. Todas las requests cuyo URI coincide con la expresión regular se procesan según los datos del bloque ubicación. Las ma­yú­s­cu­las y las mi­nú­s­cu­las se evalúan en la co­m­pa­ra­ción (case sensitive).
~* La directiva Location se in­te­r­pre­ta como expresión regular. Todas las requests cuyo URI coincide con la expresión regular se procesan según los datos del bloque ubicación. Las ma­yú­s­cu­las y las mi­nú­s­cu­las no se evalúan en la co­m­pa­ra­ción (case in­se­n­si­ti­ve).

El siguiente ejemplo muestra tres bloques de ubicación que indican cómo se tienen que editar las so­li­ci­tu­des entrantes para los dominios example.org y www.example.org:

server {
    listen 80;
    server_name example.org www.example.org;
    root /data/www;
    location / {
        index index.html index.php;
    }
    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }
location ~ \.php$ {
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

Basándose en una solicitud de cliente con el URI "http://www.example.org:80/logo.gif", nginx procede de la siguiente manera para in­te­r­pre­tar las si­guie­n­tes pe­ti­cio­nes y entregar los recursos deseados:

http://www.example.org:80/logo.gif
http://www.example.org:80/index.php

Primero, nginx determina la ubicación es­pe­cí­fi­ca del prefijo, para lo que el servidor web lee todas las Locations (ubi­ca­cio­nes) sin mo­di­fi­ca­dor de la lista y se para en la primera que coincida con la solicitud. A co­n­ti­nua­ción se leen todas las Locations marcadas con el mo­di­fi­ca­dor RegEx (~­) y también se utiliza la primera opción. Si el servidor web no encuentra ninguna ubicación RegEx apropiada, este recurrirá a la primera ubicación de prefijo como último recurso.

La solicitud "www.example.org:80/logo.gif" coincide tanto con la ubicación del prefijo / como con la expresión regular \.(gif|jpg|png)$. En este caso nginx re­pro­du­ci­ría la solicitud en co­m­bi­na­ción con el root en la ruta de archivo /data/www/logo.gif y en­tre­ga­ría el recurso co­rre­s­po­n­die­n­te al cliente. El en­ca­be­za­do expires indica cuándo se queda obsoleta una respuesta: en el ejemplo actual tras 30 días, es decir, expires 30d.

La solicitud de la página PHP con el URI "www.example.org:80/index.php" coincide tanto con la prefix location / como con la RegEx location ~ \.php$, a la que se da un tra­ta­mie­n­to pre­fe­re­n­te. nginx entrega la solicitud a un servidor FastCGI, que escucha a un localhost:9000 y es re­s­po­n­sa­ble de la tra­mi­ta­ción de co­n­te­ni­dos web dinámicos. Así, la directiva fastcgi_param coloca el parámetro FastCGI SCRIPT_FILENAME en /data/www/index.php. A co­n­ti­nua­ción se ejecuta el archivo en el servidor upstream. La variable $document_root co­rre­s­po­n­de a la directiva root, la variable $fastcgi_script_name a la parte del URI que le sigue al nombre del host y al número de puerto, es decir, /index.php.

Este pro­ce­di­mie­n­to de in­te­r­pre­ta­ción de so­li­ci­tu­des de clientes, que a simple vista puede ser algo co­m­pli­ca­do, guarda relación con los di­fe­re­n­tes campos de apli­ca­ción en los que se utiliza nginx. En co­m­pa­ra­ción con el pro­ce­di­mie­n­to principal basado en archivos del Apache HTTP Server, la in­te­r­pre­ta­ción de requests basada en URI po­si­bi­li­ta una mayor fle­xi­bi­li­dad en cuanto al tra­ta­mie­n­to de los di­fe­re­n­tes modelos de solicitud. Esto es necesario, por ejemplo, cuando nginx no funciona como servidor web, sino como servidor proxy o de correo ele­c­tró­ni­co.

En resumen

Apache se utiliza pri­n­ci­pa­l­me­n­te como servidor web e in­te­r­pre­ta las so­li­ci­tu­des de los clientes basándose sobre todo en archivos. Por el contrario, nginx trabaja no­r­ma­l­me­n­te con URI y así es capaz de ajustarse a otros patrones de so­li­ci­tu­des.

Co­n­fi­gu­ra­ción

Frente al servidor HTTP Apache, a nginx se le atribuye una mayor velocidad al entregar co­n­te­ni­dos web estáticos, lo que se debe, entre otros factores, a di­fe­re­n­cias en la co­n­fi­gu­ra­ción. Además del fichero de co­n­fi­gu­ra­ción principal httpd.conf, el servidor web Apache ofrece a los ad­mi­ni­s­tra­do­res la po­si­bi­li­dad de gestionar los niveles de di­re­c­to­rios, donde entran en juego los llamados ficheros .htaccess. En principio, estos archivos de co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­dos pueden im­ple­me­n­tar­se en cualquier di­re­c­to­rio del servidor. Las in­s­tru­c­cio­nes definidas en .htaccess hacen re­fe­re­n­cia al di­re­c­to­rio que contiene el archivo de co­n­fi­gu­ra­ción así como a sus su­b­di­re­c­to­rios. En la práctica se utilizan los ficheros .htaccess para limitar el acceso a los di­re­c­to­rios a unos usuarios de­te­r­mi­na­dos, para crear una pro­te­c­ción por co­n­tra­se­ña o para definir reglas para la na­ve­ga­ción por los di­re­c­to­rios, para los mensajes de error, las re­di­re­c­cio­nes o los co­n­te­ni­dos al­te­r­na­ti­vos.  Es im­po­r­ta­n­te señalar que todo ello puede co­n­fi­gu­rar­se de un modo central en el fichero httpd.conf. Sin embargo, .htaccess es relevante en modelos de alo­ja­mie­n­to web como el shared hosting o alo­ja­mie­n­to co­m­pa­r­ti­do, en el que el acceso al archivo de co­n­fi­gu­ra­ción central queda reservado al proveedor del hosting. La co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da vía .htaccess permite autorizar a los usuarios a ad­mi­ni­s­trar unas áreas de­te­r­mi­na­das del sistema de archivos del servidor como, por ejemplo, para di­re­c­to­rios de proyectos se­le­c­cio­na­dos, sin oto­r­gar­les acceso a la co­n­fi­gu­ra­ción principal. Además, los cambios surten efecto in­me­dia­ta­me­n­te y sin necesidad de reiniciar. Por el contrario, ngingx ofrece opciones fu­n­da­me­n­ta­les de co­n­fi­gu­ra­ción y todas las in­s­tru­c­cio­nes se definen en el fichero nginx.conf. Ac­ce­die­n­do a él, el usuario puede controlar todo el servidor. A di­fe­re­n­cia de Apache, el acceso ad­mi­ni­s­tra­ti­vo no puede re­s­tri­n­gi­r­se a los di­re­c­to­rios se­le­c­cio­na­dos, lo que tiene ventajas e in­co­n­ve­nie­n­tes. La co­n­fi­gu­ra­ción central de ngingx es menos flexible que el concepto del servidor HTTP Apache y ofrece una clara ventaja de seguridad: solo los usuarios con permisos de su­pe­ru­sua­rio pueden realizar cambios en la co­n­fi­gu­ra­ción del servidor web. Sin embargo, la de­s­ve­n­ta­ja del re­n­di­mie­n­to de la co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da vía .htaccess es más im­po­r­ta­n­te que el argumento de la seguridad. En la do­cu­me­n­ta­ción del servidor HTTP Apache los de­sa­rro­lla­do­res re­co­mie­n­dan evitar el uso de .htaccess siempre que sea posible acceder a httpd.conf debido pri­n­ci­pa­l­me­n­te al pro­ce­di­mie­n­to por el que Apache lee e in­te­r­pre­ta los archivos de co­n­fi­gu­ra­ción. Como ya se ha indicado an­te­rio­r­me­n­te, Apache sigue un esquema basado en archivos para responder a las so­li­ci­tu­des de los clientes. Debido a que la ar­qui­te­c­tu­ra de Apache permite una co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da, en el camino hacia el recurso so­li­ci­ta­do, el servidor web busca el fichero .htaccess en todos los di­re­c­to­rios a lo largo de la ruta del archivo y lee e in­te­r­pre­ta todos los archivos de co­n­fi­gu­ra­ción que recorre, un esquema que ralentiza el servidor web co­n­si­de­ra­ble­me­n­te.

Nota

En principio, los ad­mi­ni­s­tra­do­res de Apache pueden elegir si quieren recurrir a las po­si­bi­li­da­des de co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­das del servidor web y aceptar las ventajas e in­co­n­ve­nie­n­tes que implican. En la do­cu­me­n­ta­ción, los de­sa­rro­lla­do­res ponen de relieve que todos los ajustes de .htaccess pueden rea­li­zar­se mediante bloques de di­re­c­to­rio en el fichero de co­n­fi­gu­ra­ción principal httpd.conf.

Para des­ac­ti­var o re­s­tri­n­gir la co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da en Apache se debe recurrir a la directiva Allo­wO­ve­rri­de en los bloques de di­re­c­to­rio del fichero de co­n­fi­gu­ra­ción principal httpd.conf e indicar None. Esto señala al servidor web que ignore todos los ficheros .htaccess en di­re­c­to­rios de­bi­da­me­n­te co­n­fi­gu­ra­dos.

<VirtualHost *:80>
    ServerName example.com;
    ...
    DocumentRoot /data/www/example
      <Directory /data/www/example>
        AllowOverride None
        ...
      </Directory>
    ...
</VirtualHost>

La co­n­fi­gu­ra­ción del ejemplo ordena al servidor que ignore todos los ficheros .htaccess para el host example.com.

En resumen

A di­fe­re­n­cia de nginx, que está co­n­fi­gu­ra­do de forma ce­n­tra­li­za­da, Apache ofrece con .htaccess una co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da y basada en di­re­c­to­rios. Si se utilizan ficheros .htaccess, el servidor web pierde velocidad

Po­si­bi­li­da­des de extensión

Los dos se­r­vi­do­res web de nuestra co­m­pa­ra­ti­va se basan en un sistema modular en el que el software principal puede ampliarse con co­m­po­ne­n­tes adi­cio­na­les en caso necesario. Hasta la versión 1.9.10, nginx siguió una es­tra­te­gia de manejo de módulos diferente a la de su co­m­pe­ti­dor. El Apache HTTP Server ofrece dos po­si­bi­li­da­des para ampliar el software central: los módulos pueden o bien co­m­pi­lar­se durante el de­sa­rro­llo en los archivos binarios de Apache o cargarse de forma dinámica durante el tiempo de ejecución. Se pueden di­s­ti­n­guir tres ca­te­go­rías de módulos de Apache:

  • Módulo básico: los módulos básicos de Apache co­m­pre­n­den todos los co­m­po­ne­n­tes que proveen las funciones pri­n­ci­pa­les del servidor web.
  • Módulos de extensión: las ex­te­n­sio­nes son módulos de la Apache Fou­n­da­tion que se pro­po­r­cio­nan como co­m­po­ne­n­te especial de la Apache Di­s­tri­bu­tion. La do­cu­me­n­ta­ción sobre Apache ofrece una visión general sobre todos los módulos incluidos en la co­n­fi­gu­ra­ción estándar de la versión 2.4 de Apache.
  • Módulos de pro­vee­do­res externos: la Apache Fou­n­da­tion no ofrece estos módulos, sino pro­vee­do­res externos o pro­gra­ma­do­res autónomos.

En nginx, sin embargo, la mo­du­la­ri­dad se restringe a co­m­po­ne­n­tes de extensión estáticos que se tienen que compilar en el archivo binario del software principal. Para los usuarios que no estaban aco­s­tu­m­bra­dos a gestionar sus propios co­m­po­ne­n­tes de software sin el gestor de paquetes de la di­s­tri­bu­ción co­rre­s­po­n­die­n­te, este tipo de extensión de software limitó co­n­si­de­ra­ble­me­n­te la fle­xi­bi­li­dad del servidor web. A este respecto, el equipo de de­sa­rro­lla­do­res ha in­tro­du­ci­do algunas mejoras: desde la versión 1.9.11 (Release 09.02.2016), nginx soporta me­ca­ni­s­mos que permiten convertir módulos estáticos en dinámicos para que estos puedan cargarse durante el tiempo de ejecución a través de archivos de co­n­fi­gu­ra­ción. En ambos casos se emplea la API del módulo del servidor. En relación con esto hay que tener en cuenta que no todos los módulos de nginx pueden co­n­ve­r­ti­r­se en módulos dinámicos. Los módulos que parchean el código fuente del software de servidor no deben cargarse como módulos dinámicos. Además, en los ajustes básicos nginx limita a 128 el número de módulos dinámicos que pueden cargarse si­mu­l­tá­nea­me­n­te. Para au­me­n­tar­lo, otorga el valor deseado a la constante en NGX_MAX_DYNAMIC_MODULES en el código fuente de nginx. Asimismo, para los módulos oficiales de la do­cu­me­n­ta­ción de nginx los usuarios pueden recurrir a módulos de pro­vee­do­res externos.

En resumen

Ambos se­r­vi­do­res web pueden im­ple­me­n­tar­se con módulos. Además de los estáticos, también existen módulos dinámicos que, en caso necesario, pueden cargarse en el programa en curso.

Do­cu­me­n­ta­ción y asi­s­te­n­cia

Ambos proyectos de software están bien do­cu­me­n­ta­dos y ofrecen a los usuarios in­fo­r­ma­ción de primera mano a través de wikis y blogs.

Mientras que la do­cu­me­n­ta­ción de nginx solo está di­s­po­ni­ble en inglés y en ruso, el proyecto Apache se distingue por su material in­fo­r­ma­ti­vo en numerosos idiomas, aunque está des­ac­tua­li­za­do, por lo que es im­pre­s­ci­n­di­ble recurrir a la versión en inglés. La comunidad de cada proyecto open source es el medio de ayuda en caso de problemas y las listas de correo hacen las veces de foros de debate.

La tra­n­s­pa­re­n­cia sobre las posibles fechas de la­n­za­mie­n­to y las hojas de ruta ofrecen a los usuarios la po­si­bi­li­dad de adaptarse a los de­sa­rro­llos futuros. Los errores en el software y las brechas de seguridad se recopilan y se re­pro­ce­san en un informe de bugs público.

Además del proyecto open source NGINX, Nginx, Inc. ofrece el producto comercial NGINX Plus. Mediante el pago de una tarifa anual, los usuarios disfrutan de funciones adi­cio­na­les y de la asi­s­te­n­cia pro­fe­sio­nal del fa­bri­ca­n­te. En la página oficial existe una matriz co­m­pa­ra­ti­va de ambos productos. No existe una versión comercial del servidor HTTP Apache, aunque hay algunos pro­vee­do­res externos que ofrecen servicios de asi­s­te­n­cia de pago.

En resumen

Tanto el servidor Apache HTTP como nginx están lo su­fi­cie­n­te­me­n­te do­cu­me­n­ta­dos como para usarse de modo pro­fe­sio­nal en sistemas pro­du­c­ti­vos.

Co­m­pa­ti­bi­li­dad y eco­si­s­te­ma

El servidor Apache HTTP está presente en la World Wide Web desde hace más de dos décadas y, debido a su cuota de mercado, sigue siendo el estándar de facto para la puesta a di­s­po­si­ción de co­n­te­ni­dos web, a pesar de que nginx también lleva una tra­ye­c­to­ria exitosa de 15 años. Ambos se­r­vi­do­res destacan por una amplia co­m­pa­ti­bi­li­dad de pla­ta­fo­r­mas. Mientras que Apache se re­co­mie­n­da para todos los sistemas ope­ra­ti­vos de tipo UNIX y Windows, la do­cu­me­n­ta­ción de nginx indica que soporta sistemas como FreeBSD, Linux, Solaris, IBM AIX, HP-UX, macOS y Windows. Como servidor estándar, Apache destaca por su gran co­m­pa­ti­bi­li­dad con proyectos de pro­vee­do­res externos. Todos los es­tá­n­da­res web re­le­va­n­tes se integran mediante módulos y a ello hay que añadir que gran parte de los agentes de Internet están fa­mi­lia­ri­za­dos con los conceptos de Apache. Ge­ne­ra­l­me­n­te, los ad­mi­ni­s­tra­do­res y de­sa­rro­lla­do­res web realizan sus primeros proyectos en pla­ta­fo­r­mas de alo­ja­mie­n­to co­m­pa­r­ti­do de pago que se basan, en su mayoría, en Apache y permiten una co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da vía .htaccess. Asimismo, el Apache HTTP Server es parte de un paquete de programas de código abierto de de­sa­rro­llo y pruebas de software como XAMPP o AMPPS. nginx también ofrece un amplio eco­si­s­te­ma de módulos. Además, el equipo de de­sa­rro­lla­do­res colabora con diversos proyectos de software de código abierto y pro­pie­ta­rios, así como con pro­vee­do­res de in­frae­s­tru­c­tu­ras como Amazon Web Services, Windows Azure y HP.

En resumen

Ambos se­r­vi­do­res web disfrutan ya de una cierta repu­tación y sus usuarios pueden recurrir a un amplio eco­si­s­te­ma. En la relación ningx vs. Apache, este último tiene la ventaja de que en los últimos años una amplia comunidad de usuarios se ha fa­mi­lia­ri­za­do con los fu­n­da­me­n­tos del servidor web. Debido a que miles de ad­mi­ni­s­tra­do­res han examinado y mejorado el código fuente del código, ya no solo se aboga por la seguridad del servidor web. Asimismo, los usuarios nuevos se be­ne­fi­cian del gran número de ad­mi­ni­s­tra­do­res de Apache ex­pe­ri­me­n­ta­dos que asisten a la comunidad en foros o en listas de correo.

Apache vs. nginx: resumen de di­fe­re­n­cias

A pesar de las di­fe­re­n­cias en la ar­qui­te­c­tu­ra del software, ambos se­r­vi­do­res web ofrecen funciones parecidas. Apache y nginx se utilizan en es­ce­na­rios similares, pero recurren a sus propios conceptos y es­tra­te­gias para estar a la altura de las exi­ge­n­cias. La siguiente tabla recoge las ca­ra­c­te­rí­s­ti­cas pri­n­ci­pa­les de ambos proyectos de software y muestra los puntos de in­te­r­se­c­ción y di­ve­r­ge­n­cias.

Ca­ra­c­te­rí­s­ti­ca Apache nginx
Función Servidor web Servidor proxy Servidor web Servidor proxy Proxy de correo Ba­la­n­cea­dor de carga
Lenguaje de pro­gra­ma­ción C C
Sistema operativo Todas las pla­ta­fo­r­mas de tipo UNIX Windows FreeBSD Linux Solaris IBM AIX HP-UX macOS Windows
Pu­bli­ca­ción 1995 2002
Licencia Apache License v2.0 Licencia BSD (Berkeley Software Di­s­tri­bu­tion)
De­sa­rro­lla­dor Apache Software Fou­n­da­tion Nginx, Inc.
Ar­qui­te­c­tu­ra de software Basada en procesos / hilos Dirigida por eventos
Co­n­cu­rre­n­cia Mu­l­ti­pro­ce­sa­mie­n­to Multihilo Bucle de eventos
Co­n­te­ni­dos web estáticos Sí Sí
Co­n­te­ni­dos web dinámicos Sí No
In­te­r­pre­ta­ción de las so­li­ci­tu­des de los clientes Pri­n­ci­pa­l­me­n­te basada en archivos Basada en URI
Co­n­fi­gu­ra­ción Co­n­fi­gu­ra­ción ce­n­tra­li­za­da vía httpd.conf Co­n­fi­gu­ra­ción de­s­ce­n­tra­li­za­da vía .htaccess Co­n­fi­gu­ra­ción ce­n­tra­li­za­da vía nginx.conf
Po­si­bi­li­da­des de extensión Módulos estáticos Módulos dinámicos Módulos estáticos Módulos dinámicos
Do­cu­me­n­ta­ción Inglés Español Francés Alemán Danés Japonés Coreano Portugués Turco Chino Inglés Alemán
Asi­s­te­n­cia de los de­sa­rro­lla­do­res No Sí (de pago en NGINX, Inc.)
Ayuda a la comunidad Listas de correo Wiki Listas de correo Wiki

En resumen

Apache y nginx son dos proyectos open source estables y seguros, pero ninguno de los dos se erige como claro ganador y ambos se basan en de­ci­sio­nes di­fe­re­n­tes de diseño que, en función de cómo se utilice el software, plantean ventajas e in­co­n­ve­nie­n­tes.

El servidor Apache HTTP ofrece un enorme re­pe­r­to­rio de módulos que, junto a las flexibles po­si­bi­li­da­des de co­n­fi­gu­ra­ción, establece numerosos campos de apli­ca­ción. Apache funciona como software estándar para es­ce­na­rios de alo­ja­mie­n­to co­m­pa­r­ti­do y en el futuro se impondrá en este sector de actividad frente a se­r­vi­do­res web ligeros como nginx. La po­si­bi­li­dad de integrar en el servidor in­té­r­pre­tes para lenguajes de pro­gra­ma­ción como PHP, Perl, Python o Ruby di­re­c­ta­me­n­te a través de módulos permite la entrega de co­n­te­ni­dos web dinámicos sin un servidor de apli­ca­cio­nes separado. Esto convierte al servidor Apache HTTP en una solución cómoda para páginas de pequeña y mediana en­ve­r­ga­du­ra en las que los co­n­te­ni­dos se generan de forma dinámica cuando se consultan.

Por el contrario, nginx no permite ni procesar co­n­te­ni­dos web de un modo nativo ni integrar los in­té­r­pre­tes co­rre­s­po­n­die­n­tes mediante módulos y, en cualquier caso, se necesita un servidor de apli­ca­cio­nes separado, lo que puede suponer un gasto adicional in­ne­ce­sa­rio para las páginas web de pequeña y mediana en­ve­r­ga­du­ra. En los proyectos web grandes y en casos de tráfico elevado es donde se ponen de relieve los puntos fuertes de una es­tru­c­tu­ra de tales ca­ra­c­te­rí­s­ti­cas.

En general, algunos se­r­vi­do­res de apli­ca­cio­nes utilizan nginx como ba­la­n­cea­dor de carga. Este se encarga de las so­li­ci­tu­des entrantes y en función del tipo de requests decide si deben ser tra­n­s­mi­ti­das a un servidor es­pe­cia­li­za­do. nginx entrega co­n­te­ni­dos web estáticos di­re­c­ta­me­n­te, pero si un cliente, por el contrario, solicita co­n­te­ni­dos dinámicos, el ba­la­n­cea­dor de carga transmite la solicitud a un servidor de apli­ca­cio­nes previsto para ello, el cual in­te­r­pre­ta el lenguaje de pro­gra­ma­ción, agrupa los co­n­te­ni­dos so­li­ci­ta­dos para una página web y los devuelve al ba­la­n­cea­dor de carga, que los entrega al cliente. De este modo se pueden afrontar volúmenes de tráfico elevados. Además, nginx pone a di­s­po­si­ción en el caché, y durante un período de tiempo de­te­r­mi­na­do, co­n­te­ni­dos ya en­tre­ga­dos, de manera que el ba­la­n­cea­dor de carga pueda entregar de nuevo los co­n­te­ni­dos dinámicos so­li­ci­ta­dos sin que nginx tenga que volver a recurrir a un servidor de apli­ca­cio­nes.

El traslado del in­té­r­pre­te a uno o varios se­r­vi­do­res de backend separados tiene la ventaja de que el conjunto de se­r­vi­do­res puede escalarse có­mo­da­me­n­te, in­clu­ye­n­do si es necesario se­r­vi­do­res de backend adi­cio­na­les o de­s­co­ne­c­ta­n­do sistemas in­ne­ce­sa­rios. En la práctica, ante una ar­qui­te­c­tu­ra de este tipo muchos usuarios apuestan por la co­m­bi­na­ción de nginx y Apache y se valen de las fo­r­ta­le­zas de ambos se­r­vi­do­res web.

Ir al menú principal