nginx - redes - balanceo de cargas pdf
Nginx balanceo de carga de tráfico de alto volumen (3)
Aquí hay algunas buenas referencias:
http://dak1n1.com/blog/12-nginx-performance-tuning
Error del servidor: https://serverfault.com/questions/221292/tips-for-maximizing-nginx-requests-sec
Una configuración muy bien documentada del enlace dak1n1:
# This number should be, at maximum, the number of CPU cores on your system.
# (since nginx doesn''t benefit from more than one worker per CPU.)
worker_processes 24;
# Number of file descriptors used for Nginx. This is set in the OS with ''ulimit -n 200000''
# or using /etc/security/limits.conf
worker_rlimit_nofile 200000;
# only log critical errors
error_log /var/log/nginx/error.log crit
# Determines how many clients will be served by each worker process.
# (Max clients = worker_connections * worker_processes)
# "Max clients" is also limited by the number of socket connections available on the system (~64k)
worker_connections 4000;
# essential for linux, optmized to serve many clients with each thread
use epoll;
# Accept as many connections as possible, after nginx gets notification about a new connection.
# May flood worker_connections, if that option is set too low.
multi_accept on;
# Caches information about open FDs, freqently accessed files.
# Changing this setting, in my environment, brought performance up from 560k req/sec, to 904k req/sec.
# I recommend using some varient of these options, though not the specific values listed below.
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Buffer log writes to speed up IO, or disable them altogether
#access_log /var/log/nginx/access.log main buffer=16k;
access_log off;
# Sendfile copies data between one FD and other from within the kernel.
# More efficient than read() + write(), since the requires transferring data to and from the user space.
sendfile on;
# Tcp_nopush causes nginx to attempt to send its HTTP response head in one packet,
# instead of using partial frames. This is useful for prepending headers before calling sendfile,
# or for throughput optimization.
tcp_nopush on;
# don''t buffer data-sends (disable Nagle algorithm). Good for sending frequent small bursts of data in real time.
tcp_nodelay on;
# Timeout for keep-alive connections. Server will close connections after this time.
keepalive_timeout 30;
# Number of requests a client can make over the keep-alive connection. This is set high for testing.
keepalive_requests 100000;
# allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
reset_timedout_connection on;
# send the client a "request timed out" if the body is not loaded by this time. Default 60.
client_body_timeout 10;
# If the client stops reading data, free up the stale client connection after this much time. Default 60.
send_timeout 2;
# Compression. Reduces the amount of data that needs to be transferred over the network
gzip on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
gzip_disable "MSIE [1-6]/.";
También más información sobre el ajuste del sistema Linux para sysctl.conf:
# Increase system IP port limits to allow for more connections
net.ipv4.ip_local_port_range = 2000 65000
net.ipv4.tcp_window_scaling = 1
# number of packets to keep in backlog before the kernel starts dropping them
net.ipv4.tcp_max_syn_backlog = 3240000
# increase socket listen backlog
net.core.somaxconn = 3240000
net.ipv4.tcp_max_tw_buckets = 1440000
# Increase TCP buffer sizes
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_congestion_control = cubic
Durante las últimas 3 semanas hemos estado probando Nginx como balance de carga. Actualmente, no estamos logrando manejar más de 1000 conexiones req / sec y 18K activas. Cuando llegamos a los números anteriores, Nginx comienza a bloquearse y devuelve los códigos de tiempo de espera. La única forma de obtener una respuesta es reducir drásticamente el número de conexiones.
Debo tener en cuenta que mis servidores pueden y manejan esta cantidad de tráfico a diario y actualmente usamos un balanceo de DNS simple y simple.
Estamos utilizando un servidor dedicado con el siguiente HW:
- CPU INTEL XEON E5620
- 16GB de RAM
- HDD SATA 2T
- Conexión de 1Gb / s
- OS: CentOS 5.8
Necesitamos cargar los servidores 7 de Balance 7 que ejecutan Tomcat6 y que manejen más de 2000 req / seg en los tiempos de inspección, manejando las solicitudes HTTP y HTTPS.
Mientras que la ejecución del consumo de CPU de Nginx es de alrededor del 15% y la memoria RAM utilizada es de alrededor de 100 MB.
Mis preguntas son:
- ¿Alguien ha intentado equilibrar la carga con este tipo de tráfico usando nginx?
- ¿Crees que nginx puede manejar ese tráfico?
- ¿Tienes alguna idea de qué puede causar el ahorcamiento?
- ¿Me estoy perdiendo algo en mis configuraciones?
A continuación se muestran mis archivos de configuración:
nginx.conf:
user nginx;
worker_processes 10;
worker_rlimit_nofile 200000;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10000;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main ''$remote_addr - $remote_user [$time_local] "$request" ''
''$status $body_bytes_sent "$http_referer" ''
''"$http_user_agent" "$http_x_forwarded_for"'';
#access_log /var/log/nginx/access.log main;
access_log off;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
reset_timedout_connection on;
gzip on;
gzip_comp_level 1;
include /etc/nginx/conf.d/*.conf;
}
servidores.conf:
#Set the upstream (servers to load balance)
#HTTP stream
upstream adsbar {
least_conn;
server xx.xx.xx.34 max_fails=2 fail_timeout=15s;
server xx.xx.xx.36 max_fails=2 fail_timeout=15s;
server xx.xx.xx.37 max_fails=2 fail_timeout=15s;
server xx.xx.xx.39 max_fails=2 fail_timeout=15s;
server xx.xx.xx.40 max_fails=2 fail_timeout=15s;
server xx.xx.xx.42 max_fails=2 fail_timeout=15s;
server xx.xx.xx.43 max_fails=2 fail_timeout=15s;
}
#HTTPS stream
upstream adsbar-ssl {
least_conn;
server xx.xx.xx.34:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.36:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.37:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.39:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.40:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.42:443 max_fails=2 fail_timeout=15s;
server xx.xx.xx.43:443 max_fails=2 fail_timeout=15s;
}
#HTTP
server {
listen xxx.xxx.xxx.xxx:8080;
server_name www.mycompany.com;
location / {
proxy_set_header Host $host;
# So the original HTTP Host header is preserved
proxy_set_header X-Real-IP $remote_addr;
# The IP address of the client (which might be a proxy itself)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://adsbar;
}
}
#HTTPS
server {
listen xxx.xxx.xxx.xxx:8443;
server_name www.mycompany.com;
ssl on;
ssl_certificate /etc/pki/tls/certs/mycompany.crt;
# Path to an SSL certificate;
ssl_certificate_key /etc/pki/tls/private/mycompany.key;
# Path to the key for the SSL certificate;
location / {
proxy_set_header Host $host;
# So the original HTTP Host header is preserved
proxy_set_header X-Real-IP $remote_addr;
# The IP address of the client (which might be a proxy itself)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://adsbar-ssl;
}
}
server {
listen xxx.xxx.xxx.xxx:61709;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
sysctl.conf:
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values,
0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 1
# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1
# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536
# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296
fs.file-max = 120000
net.ipv4.ip_conntrack_max = 131072
net.ipv4.tcp_max_syn_backlog = 8196
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_keepalive_time = 3600
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 25165824 25165824
net.core.rmem_max = 25165824
net.core.rmem_default = 25165824
net.ipv4.tcp_wmem = 4096 65536 25165824
net.core.wmem_max = 25165824
net.core.wmem_default = 65536
net.core.optmem_max = 25165824
net.core.netdev_max_backlog = 2500
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
Cualquier ayuda, orientación, ideas serán altamente apreciadas.
Encontré que usar el algoritmo menos conectado era problemático. Cambié a
hash $remote_addr consistent;
y encontró el servicio mucho más rápido.
nginx debería poder manejar más de 1000 req / s (obtengo unos 2800 req / s en nginx cuando juego en mi computadora portátil barata con jmeter usando uno y una mitad de los 2 núcleos)
Estás usando epoll, que es la opción óptima en el kernel de Linux actual, tal como lo entiendo.
Has desactivado acces_log, por lo que tu disco IO tampoco debería ser un cuello de botella (nota: también puedes configurar access_log en modo almacenado en búfer con un gran búfer donde solo se escribe después de cada x kb, lo que evita el io del disco siendo martillado constantemente, pero mantiene los registros para su análisis)
Mi entendimiento es que para maximizar el rendimiento de nginx, normalmente establece el número de procesos de trabajador igual al número de núcleos / cpu, y luego aumenta el número de conexiones de trabajador para permitir más conexiones concurrentes (junto con el número de archivos abiertos al límite). Sin embargo, en los datos que publicó anteriormente tiene una CPU de cuatro núcleos con 10 procesos de trabajo con 10k conexiones permitidas cada una. En consecuencia, en el lado de nginx intentaría algo como:
worker_processes 4;
worker_rlimit_nofile 999999;
events {
worker_connections 32768;
use epoll;
multi_accept on;
}
En el lado del kernel, yo sintonizaría los búferes de lectura y escritura de tcp de manera diferente, usted querría un mínimo pequeño, un predeterminado pequeño y un gran máximo.
Ya has aumentado el rango de puertos efímeros.
Subiría el número de archivos abiertos límite, ya que tendrá muchos sockets abiertos.
Lo que da las siguientes líneas para agregar / cambiar en su /etc/sysctl.conf
net.ipv4.tcp_rmem = 4096 4096 25165824
net.ipv4.tcp_wmem = 4096 4096 25165824
fs.file-max=999999
Espero que ayude.