Apache vs Nginx: Guía Completa para Elegir el Servidor Web Correcto
En el mundo de los servidores web, Apache HTTP Server y Nginx dominan el panorama. Entender las diferencias entre estos dos gigantes es crucial para tomar decisiones arquitectónicas correctas.
Introducción a los Servidores Web
¿Qué es un Servidor Web?
Un servidor web es un software que acepta peticiones HTTP de clientes (navegadores) y responde con páginas web, archivos o datos. Actúa como intermediario entre el usuario y la aplicación.
Componentes de un Servidor Web:
- Motor HTTP: Procesa peticiones y respuestas
- Gestión de conexiones: Maneja múltiples clientes simultáneos
- Módulos: Extienden funcionalidad
- Configuración: Define comportamiento y reglas
Apache HTTP Server: El Veterano
Historia y Filosofía
Apache fue lanzado en 1995 y se convirtió en el servidor web más popular durante años. Su enfoque modular y flexibilidad lo hicieron dominante en los primeros días de la web.
Arquitectura de Apache
Modelo de Procesos Múltiples (MPM)
1
2
3
4
5
6
7
8
9
10
11
| # Verificar MPM activo
apache2ctl -V | grep MPM
# Prefork MPM (un proceso por conexión)
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# Worker MPM (híbrido procesos/threads)
LoadModule mpm_worker_module modules/mod_mpm_worker.so
# Event MPM (asíncrono)
LoadModule mpm_event_module modules/mod_mpm_event.so
|
Configuración de Prefork MPM
1
2
3
4
5
6
7
8
| <IfModule mpm_prefork_module>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxRequestWorkers 256
MaxConnectionsPerChild 0
</IfModule>
|
Ventajas de Apache
1. Sistema de Módulos Robusto
1
2
3
4
5
6
7
8
9
10
| # Listar módulos disponibles
apache2ctl -M
# Habilitar módulo
a2enmod rewrite
a2enmod ssl
a2enmod headers
# Deshabilitar módulo
a2dismod status
|
2. Archivo .htaccess
1
2
3
4
5
6
7
8
9
10
11
12
13
| # .htaccess para reescritura de URLs
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
# Configuración de cache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
</IfModule>
|
3. Virtual Hosts Flexibles
1
2
3
4
5
6
7
8
9
10
11
12
| <VirtualHost *:80>
ServerName ejemplo.com
DocumentRoot /var/www/ejemplo
<Directory /var/www/ejemplo>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ejemplo_error.log
CustomLog ${APACHE_LOG_DIR}/ejemplo_access.log combined
</VirtualHost>
|
Configuración Avanzada de Apache
SSL/TLS con Apache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <VirtualHost *:443>
ServerName ejemplo.com
DocumentRoot /var/www/ejemplo
SSLEngine on
SSLCertificateFile /path/to/certificate.crt
SSLCertificateKeyFile /path/to/private.key
SSLCertificateChainFile /path/to/chain.crt
# Configuración de seguridad SSL
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
</VirtualHost>
|
Nginx: El Innovador
Historia y Filosofía
Nginx fue creado en 2004 por Igor Sysoev para resolver el “problema C10K” (manejar 10,000 conexiones concurrentes). Su arquitectura asíncrona lo hace extremadamente eficiente.
Arquitectura de Nginx
Modelo Event-Driven
1
2
3
4
5
6
| # Verificar configuración de workers
nginx -t
ps aux | grep nginx
# worker_processes auto configura automáticamente
# según el número de CPUs
|
Configuración Principal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
}
|
Ventajas de Nginx
1. Alto Rendimiento
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Configuración optimizada para performance
worker_rlimit_nofile 65535;
events {
worker_connections 8192;
use epoll;
multi_accept on;
}
http {
# Buffer optimization
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;
}
|
2. Proxy Reverso Eficiente
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| upstream backend {
least_conn;
server 127.0.0.1:8000 weight=3;
server 127.0.0.1:8001 weight=2;
server 127.0.0.1:8002 backup;
}
server {
listen 80;
server_name ejemplo.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
}
|
3. Load Balancing Avanzado
1
2
3
4
5
6
7
8
9
10
11
12
13
| upstream app_servers {
# Métodos de balanceo
ip_hash; # Sesiones sticky
# least_conn; # Menos conexiones
# random; # Aleatorio
server app1.ejemplo.com:8000 max_fails=3 fail_timeout=30s;
server app2.ejemplo.com:8000 max_fails=3 fail_timeout=30s;
server app3.ejemplo.com:8000 backup;
# Health checks (Nginx Plus)
# health_check;
}
|
Comparación Detallada
Rendimiento
Manejo de Conexiones Concurrentes
1
2
3
4
5
| # Test de concurrencia con Apache Bench
ab -n 10000 -c 100 http://servidor/
# Nginx típicamente maneja más conexiones con menos recursos
# Apache consume más memoria por conexión
|
Uso de Memoria
- Apache: ~15MB por proceso worker
- Nginx: ~2-4MB total para todos los workers
Configuración
Apache (.htaccess vs nginx.conf)
1
2
3
| # Apache .htaccess (distribuido)
RewriteEngine On
RewriteRule ^api/(.*)$ /api.php?request=$1 [QSA,L]
|
1
2
3
4
| # Nginx (centralizado)
location ~* ^/api/(.*)$ {
rewrite ^/api/(.*)$ /api.php?request=$1 last;
}
|
Módulos y Extensibilidad
Apache: Módulos Dinámicos
1
2
3
4
5
6
| # Instalar módulo
apt-get install libapache2-mod-php
a2enmod php7.4
# Módulos personalizados en C
# Más fácil desarrollo de módulos
|
Nginx: Módulos Estáticos
1
2
3
4
5
| # Compilar con módulos
./configure --with-http_ssl_module --with-http_gzip_module
# Módulos de terceros requieren recompilación
# (excepto en versiones comerciales)
|
Casos de Uso Específicos
Cuándo Usar Apache
1. Shared Hosting
1
2
3
4
5
| # .htaccess permite control granular por usuario
<Directory /home/usuario/public_html>
AllowOverride All
php_admin_value open_basedir /home/usuario
</Directory>
|
2. Aplicaciones Legacy
1
2
3
| # Soporte extensivo para tecnologías antiguas
LoadModule cgi_module modules/mod_cgi.so
LoadModule perl_module modules/mod_perl.so
|
3. Desarrollo Rápido
1
2
| # Configuración inmediata sin restart
# .htaccess cambios en tiempo real
|
Cuándo Usar Nginx
1. Alto Tráfico
1
2
3
4
5
| # Optimizado para muchas conexiones simultáneas
events {
worker_connections 8192;
use epoll;
}
|
2. Microservicios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Excelente como API Gateway
upstream auth_service {
server auth:8001;
}
upstream user_service {
server users:8002;
}
location /api/auth/ {
proxy_pass http://auth_service/;
}
location /api/users/ {
proxy_pass http://user_service/;
}
|
3. Contenido Estático
1
2
3
4
5
6
| # Servir archivos estáticos eficientemente
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
|
Configuraciones Híbridas
Nginx como Frontend + Apache como Backend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # nginx.conf
upstream apache_backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name ejemplo.com;
# Contenido estático con Nginx
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
root /var/www/html;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Contenido dinámico con Apache
location / {
proxy_pass http://apache_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
| # Apache en puerto 8080
Listen 8080
<VirtualHost *:8080>
ServerName ejemplo.com
DocumentRoot /var/www/html
# Solo procesamiento dinámico
<LocationMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg)$">
Require all denied
</LocationMatch>
</VirtualHost>
|
Optimización y Tuning
MPM Event Optimization
1
2
3
4
5
6
7
| <IfModule mpm_event_module>
ServerLimit 16
MaxRequestWorkers 400
ThreadsPerChild 25
ThreadLimit 64
AsyncRequestWorkerFactor 2
</IfModule>
|
Cache Configuration
1
2
3
4
5
6
7
8
9
10
| # mod_cache_disk
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
<IfModule mod_cache.c>
CacheEnable disk /
CacheRoot /var/cache/apache2/mod_cache_disk
CacheDirLevels 2
CacheDirLength 1
</IfModule>
|
Worker Optimization
1
2
3
4
5
6
7
8
9
10
11
| # Ajustar según hardware
worker_processes auto;
worker_rlimit_nofile 65535;
worker_cpu_affinity auto;
events {
worker_connections 8192;
use epoll;
multi_accept on;
accept_mutex off;
}
|
Gzip Compression
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
|
Monitoreo y Debugging
Apache Monitoring
1
2
3
4
5
6
7
| # mod_status habilitado
curl http://localhost/server-status
curl http://localhost/server-status?auto
# Logs detallados
LogLevel debug
CustomLog logs/access.log "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D"
|
Nginx Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # stub_status module
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
# Logs personalizados
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/detailed.log detailed;
|
Conclusiones y Recomendaciones
Matriz de Decisión
Criterio | Apache | Nginx |
---|
Facilidad de configuración | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
Performance alta concurrencia | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
Uso de memoria | ⭐⭐ | ⭐⭐⭐⭐⭐ |
Flexibilidad módulos | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
Soporte .htaccess | ⭐⭐⭐⭐⭐ | ❌ |
Load balancing | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
Documentación | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
Recomendaciones Finales
- Para desarrollo y shared hosting: Apache
- Para alta concurrencia y microservicios: Nginx
- Para máxima flexibilidad: Apache
- Para mejor performance: Nginx
- Para configuración híbrida: Nginx + Apache
La elección entre Apache y Nginx no es binaria. Muchas arquitecturas modernas combinan ambos, aprovechando las fortalezas de cada uno.
Andrés Nuñez - t4ifi