Rendimiento Apache · 12 min read · Jan 26, 2026

Configurando Apache para el Máximo Rendimiento

Apache es una implementación de servidor HTTP de código abierto. Es el servidor web más popular en Internet. La Encuesta de Servidores Web de diciembre de 2005 realizada por Netcraft [

1 ] muestra que aproximadamente el 70% de los sitios web en Internet están utilizando Apache.

1. Rendimiento del servidor Apache

El rendimiento del servidor Apache se puede mejorar añadiendo recursos de hardware adicionales como RAM, CPU más rápida, etc. Pero, la mayoría de las veces, el mismo resultado se puede lograr mediante la configuración personalizada del servidor. Este artículo analiza cómo obtener el máximo rendimiento de Apache con los recursos de hardware existentes, específicamente en sistemas Linux. Por supuesto, se asume que hay suficientes recursos de hardware, especialmente suficiente RAM para que el servidor no esté intercambiando frecuentemente. Las dos primeras secciones analizan varias opciones de configuración en tiempo de compilación y en tiempo de ejecución. La sección de tiempo de ejecución asume que Apache está compilado con

prefork

MPM. La compresión HTTP y el almacenamiento en caché se discuten a continuación. Finalmente, se discute el uso de servidores separados para servir contenido estático y dinámico. Se asume un conocimiento básico de la compilación y configuración de Apache y Linux.

2 Opciones de Configuración en Tiempo de Compilación

2.1 Cargar solo los módulos requeridos:

El Servidor HTTP Apache es un programa modular donde el administrador puede elegir la funcionalidad a incluir en el servidor seleccionando un conjunto de módulos [

2 ]. Los módulos pueden ser compilados estáticamente en el binario httpd o pueden ser compilados como Objetos Compartidos Dinámicos (DSOs). Los módulos DSO pueden ser compilados cuando se construye el servidor o pueden usar la utilidad

apxs

para compilar y agregar en una fecha posterior. El módulo mod_so debe ser compilado estáticamente en el núcleo de Apache para habilitar el soporte DSO.

Ejecuta apache solo con los módulos requeridos. Esto reduce la huella de memoria y, por lo tanto, el rendimiento del servidor. Compilar módulos estáticamente ahorrará RAM que se utiliza para soportar módulos cargados dinámicamente, pero uno tiene que recompilar Apache cada vez que se agrega o se elimina un módulo. Aquí es donde el mecanismo DSO resulta útil. Una vez que el módulo mod_so está compilado estáticamente, cualquier otro módulo puede ser agregado o eliminado usando el comando LoadModule en el archivo httpd.conf; por supuesto, tendrás que compilar los módulos usando apxs si no fueron compilados cuando se construyó el servidor.

2.2 Elegir MPM apropiado:

El servidor Apache se envía con una selección de Módulos de Multiprocesamiento (MPMs) que son responsables de enlazarse a los puertos de red en la máquina, aceptar solicitudes y despachar hijos para manejar las solicitudes [

3 ]. Solo un MPM puede ser cargado en el servidor en cualquier momento.

Elegir un MPM depende de varios factores como si el SO soporta hilos, cuánta memoria está disponible, escalabilidad frente a estabilidad, si se utilizan módulos de terceros que no son seguros para hilos, etc. Los sistemas Linux pueden optar por usar un MPM con hilos como worker o un MPM sin hilos como prefork:

El MPM Worker utiliza múltiples procesos hijos. Es multihilo dentro de cada hijo y cada hilo maneja una sola conexión. Worker es rápido y altamente escalable y la huella de memoria es comparativamente baja. Es adecuado para múltiples procesadores. Por otro lado, worker es menos tolerante a módulos defectuosos y los hilos defectuosos pueden afectar a todos los hilos en un proceso hijo.

El MPM Prefork utiliza múltiples procesos hijos, cada hijo maneja una conexión a la vez. Prefork es adecuado para sistemas de CPU única o doble, la velocidad es comparable a la de worker y es altamente tolerante a módulos defectuosos y a hijos que se bloquean. Pero el uso de memoria es alto, más tráfico lleva a un mayor uso de memoria.

3 Opciones de Configuración en Tiempo de Ejecución

3.1 Búsqueda de DNS:

La directiva HostnameLookups habilita la búsqueda de DNS para que los nombres de host puedan ser registrados en lugar de la dirección IP. Esto añade latencia a cada solicitud ya que la búsqueda de DNS debe completarse antes de que la solicitud finalice. HostnameLookups está desactivado por defecto en Apache 1.3 y versiones superiores. Déjalo desactivado y utiliza un programa de post-procesamiento como logresolve para resolver direcciones IP en los archivos de registro de acceso de Apache. Logresolve se envía con Apache.

Al usar las directivas Allow from o Deny from, utiliza la dirección IP en lugar de un nombre de dominio o un nombre de host. De lo contrario, se realiza una doble búsqueda de DNS para asegurarse de que el nombre de dominio o el nombre de host no esté siendo suplantado.

3.2 AllowOverride:

Si AllowOverride no está configurado como ‘None’, entonces Apache intentará abrir el archivo .htaccess (como se especifica en la directiva AccessFileName) en cada directorio que visita. Por ejemplo:

DocumentRoot /var/www/html  
   
 AllowOverride all  
 

Si se realiza una solicitud para el URI /index.html, entonces Apache intentará abrir /.htaccess, /var/.htaccess, /var/www/.htaccess y /var/www/html/.htaccess. Estas búsquedas adicionales en el sistema de archivos añaden latencia. Si .htaccess es necesario para un directorio particular, entonces habilítalo solo para ese directorio.

3.3 FollowSymLinks y SymLinksIfOwnerMatch:

Si la opción FollowSymLinks está configurada, entonces el servidor seguirá enlaces simbólicos en este directorio. Si SymLinksIfOwnerMatch está configurado, entonces el servidor seguirá enlaces simbólicos solo si el archivo o directorio de destino es propiedad del mismo usuario que el enlace.

Si SymLinksIfOwnerMatch está configurado, entonces Apache tendrá que emitir llamadas al sistema adicionales para verificar si la propiedad del enlace y el archivo de destino coinciden. También se necesitan llamadas al sistema adicionales cuando FollowSymLinks NO está configurado. Por ejemplo:

 DocumentRoot /vaw/www/html   
    
 Options SymLinksIfOwnerMatch   
  

Para una solicitud hecha para el URI /index.html, Apache realizará lstat() en /var, /var/www, /var/www/html y /var/www/html/index.html. Estas llamadas al sistema adicionales añadirán latencia. Los resultados de lstat no se almacenan en caché, por lo que ocurrirán en cada solicitud.

Para un rendimiento máximo, configura FollowSymLinks en todas partes y nunca configures SymLinksIfOwnerMatch. O, si SymLinksIfOwnerMatch es necesario para un directorio, entonces configúralo solo para ese directorio.

3.4 Negociación de Contenido:

Evita la negociación de contenido para una respuesta rápida. Si se requiere negociación de contenido para el sitio, utiliza archivos de tipo mapa en lugar de la directiva Options MultiViews. Con MultiViews, Apache tiene que escanear el directorio en busca de archivos, lo que añade latencia.

3.5 MaxClients:

El MaxClients establece el límite en el número máximo de solicitudes simultáneas que puede soportar el servidor. No se generan más procesos hijos que este número. No debe configurarse demasiado bajo de modo que nuevas conexiones se coloquen en cola, lo que eventualmente provoca un tiempo de espera y los recursos del servidor quedan sin usar. Configurarlo demasiado alto hará que el servidor comience a intercambiar y el tiempo de respuesta se degradará drásticamente. El valor apropiado para MaxClients se puede calcular como: MaxClients = RAM total dedicada al servidor web / Tamaño máximo del proceso hijo —- [

4 ] El tamaño del proceso hijo para servir archivos estáticos es de aproximadamente 2-3M. Para contenido dinámico como PHP, puede ser alrededor de 15M. La columna RSS en

"ps -ylC httpd --sort:rss"

muestra el uso de memoria física no intercambiada por los procesos de Apache en kilobytes.

Si hay más usuarios concurrentes que MaxClients, las solicitudes se pondrán en cola hasta un número basado en la directiva ListenBacklog. Aumenta ServerLimit para establecer MaxClients por encima de 256.

3.6 MinSpareServers, MaxSpareServers y StartServers:

MaxSpareServers y MinSpareServers determinan cuántos procesos hijos mantener mientras se esperan solicitudes. Si MinSpareServers es demasiado bajo y llegan un montón de solicitudes, entonces Apache tendrá que generar procesos hijos adicionales para servir las solicitudes. Crear procesos hijos es relativamente costoso. Si el servidor está ocupado creando procesos hijos, no podrá servir las solicitudes de los clientes de inmediato. MaxSpareServers no debe configurarse demasiado alto, puede causar problemas de recursos ya que los procesos hijos consumen recursos.

Ajusta MinSpareServers y MaxSpareServers de tal manera que Apache no tenga que generar frecuentemente más de 4 procesos hijos por segundo (Apache puede generar un máximo de 32 procesos hijos por segundo). Cuando se generan más de 4 hijos por segundo, se registrará un mensaje en el ErrorLog.

La directiva StartServers establece el número de procesos de servidor hijo creados al inicio. Apache continuará creando procesos hijos hasta que se alcance la configuración de MinSpareServers. No tiene mucho efecto en el rendimiento si el servidor no se reinicia con frecuencia. Si hay muchas solicitudes y Apache se reinicia con frecuencia, establece esto en un valor relativamente alto.

3.7 MaxRequestsPerChild:

La directiva MaxRequestsPerChild establece el límite en el número de solicitudes que un proceso de servidor hijo individual manejará. Después de MaxRequestsPerChild solicitudes, el proceso hijo morirá. Está configurado en 0 por defecto, lo que significa que el proceso hijo nunca expirará. Es apropiado establecer esto en un valor de algunos miles. Esto puede ayudar a prevenir fugas de memoria ya que el proceso muere después de servir un cierto número de solicitudes. No lo configures demasiado bajo, ya que crear nuevos procesos tiene sobrecarga.

3.8 KeepAlive y KeepAliveTimeout:

La directiva KeepAlive permite que múltiples solicitudes se envíen a través de la misma conexión TCP. Esto es particularmente útil al servir páginas HTML con muchas imágenes. Si KeepAlive está configurado como Off, entonces para cada imagen, se debe hacer una conexión TCP separada. La sobrecarga debida al establecimiento de la conexión TCP se puede eliminar activando KeepAlive.

KeepAliveTimeout determina cuánto tiempo esperar por la siguiente solicitud. Establece esto en un valor bajo, quizás entre dos y cinco segundos. Si se establece demasiado alto, los procesos hijos están ocupados esperando al cliente cuando podrían ser utilizados para servir nuevos clientes.

4 Compresión HTTP y Almacenamiento en Caché

La compresión HTTP está completamente especificada en HTTP/1.1. El servidor utiliza el método de codificación gzip o deflate para el payload de respuesta antes de enviarlo al cliente. El cliente luego descomprime el payload. No hay necesidad de instalar ningún software adicional en el lado del cliente ya que todos los navegadores principales lo soportan. Usar compresión ahorrará ancho de banda y mejorará el tiempo de respuesta, los estudios han encontrado una ganancia media de compresión del 75.2 % [

5 ]. La compresión HTTP se puede habilitar en Apache usando el módulo

mod_deflate

. El payload se comprime solo si el navegador solicita compresión, de lo contrario se sirve contenido sin comprimir. Un navegador consciente de la compresión informa al servidor que prefiere contenido comprimido a través del encabezado de solicitud HTTP - “Accept-Encoding: gzip,deflate”. Luego, el servidor responde con un payload comprimido y el encabezado de respuesta configurado a “

Content-Encoding:  
gzip

El siguiente ejemplo utiliza telnet para ver los encabezados de solicitud y respuesta:

bash-3.00$ telnet www.webperformance.org 80  
 Intentando 24.60.234.27...  
 Conectado a www.webperformance.org (24.60.234.27).  
 El carácter de escape es '^]'.  
 HEAD / HTTP/1.1  
 Host: www.webperformance.org  
 Accept-Encoding: gzip,deflate  
   
 HTTP/1.1 200 OK  
 Fecha: Sáb, 31 Dic 2005 02:29:22 GMT  
 Servidor: Apache/2.0  
 X-Powered-By: PHP/5.1.1  
 Cache-Control: max-age=0  
 Expires: Sáb, 31 Dic 2005 02:29:22 GMT  
 Vary: Accept-Encoding  
 Content-Encoding: gzip  
 Content-Length: 20  
 Content-Type: text/html; charset=ISO-8859-1  
 

En el almacenamiento en caché, se almacena una copia de los datos en el cliente o en un servidor proxy para que no tenga que ser recuperada frecuentemente del servidor. Esto ahorrará ancho de banda, disminuirá la carga en el servidor y reducirá la latencia. El control de caché se realiza a través de encabezados HTTP. En Apache, esto se puede lograr a través de los módulos mod_expires y mod_headers. También hay almacenamiento en caché del lado del servidor, en el que los contenidos de acceso frecuente se almacenan en memoria para que puedan ser servidos rápidamente. El módulo mod_cache se puede utilizar para el almacenamiento en caché del lado del servidor, es estable en producción en la versión 2.2 de Apache.

5 Servidor separado para contenido estático y dinámico

Los procesos de Apache que sirven contenido dinámico utilizan entre 3M y 20M de RAM. Crece para acomodar el contenido que está sirviendo y nunca disminuye hasta que el proceso muere. Supongamos que un proceso de Apache crece a 20M para servir un contenido dinámico. Después de completar la solicitud, está libre para servir cualquier otra solicitud. Si llega una solicitud para una imagen, entonces este proceso de 20M está sirviendo un contenido estático que podría ser servido por un proceso de 1M. La memoria se utiliza de manera ineficiente.

Utiliza un Apache pequeño (con módulos mínimos compilados estáticamente) como el servidor frontal para servir contenidos estáticos. Las solicitudes de contenidos dinámicos se reenvían al Apache pesado (compilado con todos los módulos requeridos). Usar un servidor frontal ligero tiene la ventaja de que los contenidos estáticos se sirven rápidamente sin mucho uso de memoria y solo los contenidos dinámicos se pasan al servidor pesado.

El reenvío de solicitudes se puede lograr utilizando los módulos mod_proxy y rewrite_module. Supongamos que hay un servidor Apache ligero escuchando en el puerto 80 y el Apache pesado escuchando en el puerto 8088. Entonces, la siguiente configuración en el Apache ligero se puede usar para reenviar todas las solicitudes excepto las solicitudes de imágenes al servidor pesado.

ProxyPassReverse / http://%{HTTP_HOST}:8088/  
 RewriteEngine on                                             ---- [9]  
 RewriteCond   %{REQUEST_URI} !.*\.(gif|png|jpg)$  
 RewriteRule ^/(.*) http://%{HTTP_HOST}:8088/$1 [P]

Todas las solicitudes, excepto las de imágenes, se envían al servidor de backend. La respuesta es recibida por el servidor frontal y luego suministrada al cliente. En lo que respecta al cliente, todas las respuestas parecen provenir de un solo servidor.

6 Conclusión

Configurar Apache para el máximo rendimiento es complicado, no hay reglas estrictas. Comprende los requisitos del servidor web y experimenta con varias opciones disponibles. Usa herramientas como

ab

y

httperf

para medir el rendimiento del servidor web. Servidores ligeros como tux , thttpd pueden también ser utilizados como el servidor frontal. Si se utiliza un servidor de base de datos, asegúrate de que esté optimizado para que no cree ningún cuello de botella. En el caso de MySQL,

mtop puede ser utilizado para monitorear consultas lentas. El rendimiento de los scripts PHP se puede mejorar utilizando un producto de caché de PHP como

Turck MMCache . Elimina la sobrecarga debida a la compilación almacenando en caché los scripts PHP en estado compilado.

Bibliografía

1 http://news.netcraft.com/archives/web_server_survey.html

2 http://httpd.apache.org/docs/2.2/dso.html

3 http://httpd.apache.org/docs/2.2/mpm.html

4 http://modperlbook.org/html/ch11_01.html

5 http://www.speedupyoursite.com/18/18-2t.html

6 http://www.xs4all.nl/~thomas/apachecon/PerformanceTuning.html

7 http://www.onlamp.com/pub/a/onlamp/2004/02/05/lamp_tuning.html

8 http://httpd.apache.org/docs/2.2/misc/perf-tuning.html

9 Linux Server Hacks por Rob Flickenger

Biografía del autor: Vishnu Ram tiene un MTech. en Sistemas de Comunicación del IIT Madras. Se unió a Bobcares en 2003 y ha estado trabajando para Poornam desde entonces.

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.